package site import ( "RenewCMS/api/pkg/apperr" validator "RenewCMS/api/pkg/validator" "RenewCMS/internal/infrastructure/useCases" "encoding/json" "log" "net/http" "net/url" "strconv" "time" "github.com/go-chi/chi/v5" ) const ( defaultSitemapPage = 1 defaultSitemapSize = 100 totalCountHeader = "X-Total-Count" ) type SitemapHandler struct { ListUseCase *useCases.ListSitemapUseCase } func NewSitemapHandler(list *useCases.ListSitemapUseCase) *SitemapHandler { return &SitemapHandler{ListUseCase: list} } type sitemapQuery struct { Page int `validate:"gte=1"` Size int `validate:"oneof=25 50 100 500"` } type sitemapItem struct { URL string `json:"url"` ModifiedAt string `json:"modified_at"` Noindex bool `json:"noindex"` } func sitemapIntParam(values url.Values, name string, fallback int) (int, error) { if !values.Has(name) { return fallback, nil } return strconv.Atoi(values.Get(name)) } func readSitemapQuery(values url.Values) (sitemapQuery, error) { page, err := sitemapIntParam(values, "page", defaultSitemapPage) if err != nil { return sitemapQuery{}, err } size, err := sitemapIntParam(values, "size", defaultSitemapSize) if err != nil { return sitemapQuery{}, err } return sitemapQuery{Page: page, Size: size}, nil } func (h *SitemapHandler) Sitemap(w http.ResponseWriter, r *http.Request) { query, err := readSitemapQuery(r.URL.Query()) if err != nil || validator.Validate.Struct(query) != nil { http.Error(w, apperr.BodyErrorMessage, http.StatusBadRequest) return } page, err := h.ListUseCase.List(chi.URLParam(r, "key"), query.Page, query.Size) if err != nil { writeSiteError(w, err) return } items := make([]sitemapItem, 0, len(page.Entries)) for _, entry := range page.Entries { items = append(items, sitemapItem{URL: entry.URL, ModifiedAt: entry.ModifiedAt.UTC().Format(time.RFC3339), Noindex: entry.Noindex}) } body, err := json.Marshal(items) if err != nil { http.Error(w, "Failed to encode response", http.StatusInternalServerError) return } w.Header().Set(totalCountHeader, strconv.Itoa(page.Total)) if _, err := w.Write(body); err != nil { log.Printf("Failed to write response: %v", err) } }