···
+
"Coves/internal/core/communityFeeds"
+
// GetCommunityHandler handles community feed retrieval
+
type GetCommunityHandler struct {
+
service communityFeeds.Service
+
// NewGetCommunityHandler creates a new community feed handler
+
func NewGetCommunityHandler(service communityFeeds.Service) *GetCommunityHandler {
+
return &GetCommunityHandler{
+
// HandleGetCommunity retrieves posts from a community with sorting
+
// GET /xrpc/social.coves.communityFeed.getCommunity?community={did_or_handle}&sort=hot&limit=15&cursor=...
+
func (h *GetCommunityHandler) HandleGetCommunity(w http.ResponseWriter, r *http.Request) {
+
if r.Method != http.MethodGet {
+
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
+
// Parse query parameters
+
req, err := h.parseRequest(r)
+
writeError(w, http.StatusBadRequest, "InvalidRequest", err.Error())
+
// Alpha: No viewer context needed for basic community sorting
+
// TODO(feed-generator): Extract viewer DID when implementing viewer-specific state
+
// (blocks, upvotes, saves) in feed generator skeleton
+
response, err := h.service.GetCommunityFeed(r.Context(), req)
+
handleServiceError(w, err)
+
w.Header().Set("Content-Type", "application/json")
+
w.WriteHeader(http.StatusOK)
+
if err := json.NewEncoder(w).Encode(response); err != nil {
+
// Log encoding errors but don't return error response (headers already sent)
+
log.Printf("ERROR: Failed to encode feed response: %v", err)
+
// parseRequest parses query parameters into GetCommunityFeedRequest
+
func (h *GetCommunityHandler) parseRequest(r *http.Request) (communityFeeds.GetCommunityFeedRequest, error) {
+
req := communityFeeds.GetCommunityFeedRequest{}
+
req.Community = r.URL.Query().Get("community")
+
// Optional: sort (default: hot)
+
req.Sort = r.URL.Query().Get("sort")
+
// Optional: timeframe (default: day for top sort)
+
req.Timeframe = r.URL.Query().Get("timeframe")
+
if req.Timeframe == "" && req.Sort == "top" {
+
// Optional: limit (default: 15, max: 50)
+
if limitStr := r.URL.Query().Get("limit"); limitStr != "" {
+
if limit, err := strconv.Atoi(limitStr); err == nil {
+
if cursor := r.URL.Query().Get("cursor"); cursor != "" {