feat: add books APIs
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/prabhupadasays/spsays-bff/internal/repository"
|
||||
"github.com/prabhupadasays/spsays-bff/pkg/response"
|
||||
)
|
||||
|
||||
type GlossaryHandler struct {
|
||||
repo *repository.GlossaryRepo
|
||||
}
|
||||
|
||||
func NewGlossaryHandler(repo *repository.GlossaryRepo) *GlossaryHandler {
|
||||
return &GlossaryHandler{repo: repo}
|
||||
}
|
||||
|
||||
// List returns all glossary entries sorted by term.
|
||||
// GET /glossary
|
||||
func (h *GlossaryHandler) List(w http.ResponseWriter, r *http.Request) {
|
||||
docs, err := h.repo.GetAll(r.Context())
|
||||
if err != nil {
|
||||
response.Error(w, http.StatusInternalServerError, "failed to fetch glossary")
|
||||
return
|
||||
}
|
||||
response.JSON(w, http.StatusOK, docs)
|
||||
}
|
||||
|
||||
// GetByTerm returns a single glossary entry by exact term match.
|
||||
// GET /glossary/term/{term}
|
||||
func (h *GlossaryHandler) GetByTerm(w http.ResponseWriter, r *http.Request) {
|
||||
term := chi.URLParam(r, "term")
|
||||
doc, err := h.repo.GetByTerm(r.Context(), term)
|
||||
if err != nil {
|
||||
response.Error(w, http.StatusInternalServerError, "failed to fetch term")
|
||||
return
|
||||
}
|
||||
if doc == nil {
|
||||
response.Error(w, http.StatusNotFound, "term not found")
|
||||
return
|
||||
}
|
||||
response.JSON(w, http.StatusOK, doc)
|
||||
}
|
||||
|
||||
// GetByLetter returns all glossary entries whose term starts with the given
|
||||
// base letter (including diacritical variants like Ā→A, Ś→S, etc.).
|
||||
// GET /glossary/letter/{letter}
|
||||
func (h *GlossaryHandler) GetByLetter(w http.ResponseWriter, r *http.Request) {
|
||||
letter := chi.URLParam(r, "letter")
|
||||
if len(letter) != 1 {
|
||||
response.Error(w, http.StatusBadRequest, "letter must be a single character")
|
||||
return
|
||||
}
|
||||
|
||||
docs, err := h.repo.GetByLetter(r.Context(), letter)
|
||||
if err != nil {
|
||||
response.Error(w, http.StatusInternalServerError, "failed to fetch glossary entries")
|
||||
return
|
||||
}
|
||||
if docs == nil {
|
||||
docs = []repository.GlossaryEntryDoc{}
|
||||
}
|
||||
response.JSON(w, http.StatusOK, docs)
|
||||
}
|
||||
|
||||
// GetTermsByLetter returns lightweight term summaries (no definitions) for a
|
||||
// given base letter. Used for sidebar listing.
|
||||
// GET /glossary/letter/{letter}/terms
|
||||
func (h *GlossaryHandler) GetTermsByLetter(w http.ResponseWriter, r *http.Request) {
|
||||
letter := chi.URLParam(r, "letter")
|
||||
if len(letter) != 1 {
|
||||
response.Error(w, http.StatusBadRequest, "letter must be a single character")
|
||||
return
|
||||
}
|
||||
|
||||
docs, err := h.repo.GetTermsByLetter(r.Context(), letter)
|
||||
if err != nil {
|
||||
response.Error(w, http.StatusInternalServerError, "failed to fetch terms")
|
||||
return
|
||||
}
|
||||
if docs == nil {
|
||||
docs = []repository.GlossaryTermSummary{}
|
||||
}
|
||||
response.JSON(w, http.StatusOK, docs)
|
||||
}
|
||||
|
||||
// GetLetterCounts returns the count of glossary entries per base letter.
|
||||
// GET /glossary/letters
|
||||
func (h *GlossaryHandler) GetLetterCounts(w http.ResponseWriter, r *http.Request) {
|
||||
counts, 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, counts)
|
||||
}
|
||||
Reference in New Issue
Block a user