GetHosts handles GET /packages/:packageId/hosts.
(w http.ResponseWriter, r *http.Request)
| 87 | |
| 88 | // GetHosts handles GET /packages/:packageId/hosts. |
| 89 | func (h *PackagesHandler) GetHosts(w http.ResponseWriter, r *http.Request) { |
| 90 | packageID := chi.URLParam(r, "packageId") |
| 91 | if packageID == "" { |
| 92 | Error(w, http.StatusBadRequest, "packageId is required") |
| 93 | return |
| 94 | } |
| 95 | q := r.URL.Query() |
| 96 | page, _ := strconv.Atoi(q.Get("page")) |
| 97 | if page <= 0 { |
| 98 | page = 1 |
| 99 | } |
| 100 | limit, _ := strconv.Atoi(q.Get("limit")) |
| 101 | if limit <= 0 { |
| 102 | limit = 25 |
| 103 | } |
| 104 | if limit > 500 { |
| 105 | limit = 500 |
| 106 | } |
| 107 | search := q.Get("search") |
| 108 | if len(search) > 200 { |
| 109 | search = search[:200] |
| 110 | } |
| 111 | params := store.GetHostsParams{ |
| 112 | Page: page, |
| 113 | Limit: limit, |
| 114 | Search: search, |
| 115 | } |
| 116 | if v := q.Get("needsUpdate"); v != "" { |
| 117 | if b, err := strconv.ParseBool(v); err == nil { |
| 118 | params.NeedsUpdate = &b |
| 119 | } |
| 120 | } |
| 121 | hosts, total, err := h.packages.GetHosts(r.Context(), packageID, params) |
| 122 | if err != nil { |
| 123 | Error(w, http.StatusInternalServerError, "Failed to fetch package hosts") |
| 124 | return |
| 125 | } |
| 126 | pages := (total + params.Limit - 1) / params.Limit |
| 127 | if pages < 1 { |
| 128 | pages = 1 |
| 129 | } |
| 130 | JSON(w, http.StatusOK, map[string]interface{}{ |
| 131 | "hosts": hosts, |
| 132 | "pagination": map[string]interface{}{ |
| 133 | "page": params.Page, |
| 134 | "limit": params.Limit, |
| 135 | "total": total, |
| 136 | "pages": pages, |
| 137 | }, |
| 138 | }) |
| 139 | } |
| 140 | |
| 141 | // GetActivity handles GET /packages/:packageId/activity. |
| 142 | func (h *PackagesHandler) GetActivity(w http.ResponseWriter, r *http.Request) { |