117 lines
3.6 KiB
Go
117 lines
3.6 KiB
Go
package handler
|
|
|
|
import (
|
|
"net/http"
|
|
|
|
"github.com/prabhupadasays/spsays-bff/internal/repository"
|
|
"github.com/prabhupadasays/spsays-bff/pkg/response"
|
|
)
|
|
|
|
type DiscipleHandler struct {
|
|
repo *repository.DiscipleRepo
|
|
// users (Postgres) resolves which disciples have a platform account
|
|
// linked by an admin. Separate store from the disciple records
|
|
// themselves, hence the second dependency.
|
|
users *repository.UserRepo
|
|
}
|
|
|
|
func NewDiscipleHandler(repo *repository.DiscipleRepo, users *repository.UserRepo) *DiscipleHandler {
|
|
return &DiscipleHandler{repo: repo, users: users}
|
|
}
|
|
|
|
// Linked — GET /disciples/linked — every disciple that has a platform account,
|
|
// as {disciple_id, handle, name, avatar_url}. Public and unpaged: only Śrīla
|
|
// Prabhupāda's own disciples are ever linked, so the set is tiny and the
|
|
// /disciples browser fetches it once to highlight the matching cards.
|
|
func (h *DiscipleHandler) Linked(w http.ResponseWriter, r *http.Request) {
|
|
if h.users == nil {
|
|
// Degraded boot without Postgres — an empty set just means "no
|
|
// highlights", which is a fine reading experience.
|
|
response.JSON(w, http.StatusOK, []repository.DiscipleLink{})
|
|
return
|
|
}
|
|
links, err := h.users.ListDiscipleLinks(r.Context())
|
|
if err != nil {
|
|
response.Error(w, http.StatusInternalServerError, "failed to fetch linked disciples")
|
|
return
|
|
}
|
|
response.JSON(w, http.StatusOK, links)
|
|
}
|
|
|
|
func (h *DiscipleHandler) List(w http.ResponseWriter, r *http.Request) {
|
|
letter := r.URL.Query().Get("letter")
|
|
suffix := r.URL.Query().Get("suffix")
|
|
|
|
var letterPtr, suffixPtr *string
|
|
if letter != "" && letter != "All" {
|
|
letterPtr = &letter
|
|
}
|
|
if suffix != "" {
|
|
suffixPtr = &suffix
|
|
}
|
|
|
|
docs, err := h.repo.GetByLetterAndSuffix(r.Context(), letterPtr, suffixPtr)
|
|
if err != nil {
|
|
response.Error(w, http.StatusInternalServerError, "failed to fetch disciples")
|
|
return
|
|
}
|
|
response.JSON(w, http.StatusOK, docs)
|
|
}
|
|
|
|
func (h *DiscipleHandler) Count(w http.ResponseWriter, r *http.Request) {
|
|
letter := r.URL.Query().Get("letter")
|
|
suffix := r.URL.Query().Get("suffix")
|
|
|
|
var letterPtr, suffixPtr *string
|
|
if letter != "" && letter != "All" {
|
|
letterPtr = &letter
|
|
}
|
|
if suffix != "" {
|
|
suffixPtr = &suffix
|
|
}
|
|
|
|
total, err := h.repo.Count(r.Context())
|
|
if err != nil {
|
|
response.Error(w, http.StatusInternalServerError, "failed to count disciples")
|
|
return
|
|
}
|
|
filtered, err := h.repo.CountFiltered(r.Context(), letterPtr, suffixPtr)
|
|
if err != nil {
|
|
response.Error(w, http.StatusInternalServerError, "failed to count filtered disciples")
|
|
return
|
|
}
|
|
response.JSON(w, http.StatusOK, map[string]int64{"total": total, "filtered": filtered})
|
|
}
|
|
|
|
func (h *DiscipleHandler) LetterCounts(w http.ResponseWriter, r *http.Request) {
|
|
docs, err := h.repo.GetLetterCounts(r.Context())
|
|
if err != nil {
|
|
response.Error(w, http.StatusInternalServerError, "failed to fetch letter counts")
|
|
return
|
|
}
|
|
response.JSON(w, http.StatusOK, docs)
|
|
}
|
|
|
|
func (h *DiscipleHandler) SuffixCounts(w http.ResponseWriter, r *http.Request) {
|
|
docs, err := h.repo.GetSuffixCounts(r.Context())
|
|
if err != nil {
|
|
response.Error(w, http.StatusInternalServerError, "failed to fetch suffix counts")
|
|
return
|
|
}
|
|
response.JSON(w, http.StatusOK, docs)
|
|
}
|
|
|
|
func (h *DiscipleHandler) Search(w http.ResponseWriter, r *http.Request) {
|
|
query := r.URL.Query().Get("q")
|
|
if query == "" {
|
|
response.Error(w, http.StatusBadRequest, "search query is required")
|
|
return
|
|
}
|
|
docs, err := h.repo.Search(r.Context(), query, 100)
|
|
if err != nil {
|
|
response.Error(w, http.StatusInternalServerError, "failed to search disciples")
|
|
return
|
|
}
|
|
response.JSON(w, http.StatusOK, docs)
|
|
}
|