A community based topic aggregation platform built on atproto
1package discover
2
3import (
4 "encoding/json"
5 "log"
6 "net/http"
7 "strconv"
8
9 "Coves/internal/core/discover"
10)
11
12// GetDiscoverHandler handles discover feed retrieval
13type GetDiscoverHandler struct {
14 service discover.Service
15}
16
17// NewGetDiscoverHandler creates a new discover handler
18func NewGetDiscoverHandler(service discover.Service) *GetDiscoverHandler {
19 return &GetDiscoverHandler{
20 service: service,
21 }
22}
23
24// HandleGetDiscover retrieves posts from all communities (public feed)
25// GET /xrpc/social.coves.feed.getDiscover?sort=hot&limit=15&cursor=...
26// Public endpoint - no authentication required
27func (h *GetDiscoverHandler) HandleGetDiscover(w http.ResponseWriter, r *http.Request) {
28 if r.Method != http.MethodGet {
29 http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
30 return
31 }
32
33 // Parse query parameters
34 req := h.parseRequest(r)
35
36 // Get discover feed
37 response, err := h.service.GetDiscover(r.Context(), req)
38 if err != nil {
39 handleServiceError(w, err)
40 return
41 }
42
43 // Return feed
44 w.Header().Set("Content-Type", "application/json")
45 w.WriteHeader(http.StatusOK)
46 if err := json.NewEncoder(w).Encode(response); err != nil {
47 log.Printf("ERROR: Failed to encode discover response: %v", err)
48 }
49}
50
51// parseRequest parses query parameters into GetDiscoverRequest
52func (h *GetDiscoverHandler) parseRequest(r *http.Request) discover.GetDiscoverRequest {
53 req := discover.GetDiscoverRequest{}
54
55 // Optional: sort (default: hot)
56 req.Sort = r.URL.Query().Get("sort")
57 if req.Sort == "" {
58 req.Sort = "hot"
59 }
60
61 // Optional: timeframe (default: day for top sort)
62 req.Timeframe = r.URL.Query().Get("timeframe")
63 if req.Timeframe == "" && req.Sort == "top" {
64 req.Timeframe = "day"
65 }
66
67 // Optional: limit (default: 15, max: 50)
68 req.Limit = 15
69 if limitStr := r.URL.Query().Get("limit"); limitStr != "" {
70 if limit, err := strconv.Atoi(limitStr); err == nil {
71 req.Limit = limit
72 }
73 }
74
75 // Optional: cursor
76 if cursor := r.URL.Query().Get("cursor"); cursor != "" {
77 req.Cursor = &cursor
78 }
79
80 return req
81}