package api import ( "encoding/json" "errors" "net/http" "strconv" "github.com/go-chi/chi/v5" "github.com/syonad/clonepack/internal/core" "github.com/syonad/clonepack/internal/store" ) type RepoHandler struct { svc *core.RepoService } func NewRepoHandler(svc *core.RepoService) *RepoHandler { return &RepoHandler{svc: svc} } func (h *RepoHandler) Create(w http.ResponseWriter, r *http.Request) { var req CreateRepoRequest if err := json.NewDecoder(r.Body).Decode(&req); err != nil { Error(w, http.StatusBadRequest, "invalid JSON") return } repo, err := h.svc.Create(r.Context(), core.CreateRepoInput{ Name: req.Name, Type: req.Type, SourceURL: req.SourceURL, SyncMode: req.SyncMode, }) if err != nil { Error(w, http.StatusUnprocessableEntity, err.Error()) return } JSON(w, http.StatusCreated, repoToResponse(repo)) } func (h *RepoHandler) List(w http.ResponseWriter, r *http.Request) { repos, err := h.svc.List(r.Context()) if err != nil { Error(w, http.StatusInternalServerError, err.Error()) return } items := make([]RepoResponse, len(repos)) for i, repo := range repos { items[i] = repoToResponse(&repo) } JSON(w, http.StatusOK, ListReposResponse{Items: items, Total: len(items)}) } func (h *RepoHandler) Get(w http.ResponseWriter, r *http.Request) { id, err := strconv.ParseInt(chi.URLParam(r, "id"), 10, 64) if err != nil { Error(w, http.StatusBadRequest, "invalid id") return } repo, err := h.svc.Get(r.Context(), id) if errors.Is(err, store.ErrNotFound) { Error(w, http.StatusNotFound, "repo not found") return } if err != nil { Error(w, http.StatusInternalServerError, err.Error()) return } JSON(w, http.StatusOK, repoToResponse(repo)) } func (h *RepoHandler) Delete(w http.ResponseWriter, r *http.Request) { id, err := strconv.ParseInt(chi.URLParam(r, "id"), 10, 64) if err != nil { Error(w, http.StatusBadRequest, "invalid id") return } if err := h.svc.Delete(r.Context(), id); errors.Is(err, store.ErrNotFound) { Error(w, http.StatusNotFound, "repo not found") return } else if err != nil { Error(w, http.StatusInternalServerError, err.Error()) return } w.WriteHeader(http.StatusNoContent) } func repoToResponse(r *store.Repo) RepoResponse { return RepoResponse{ ID: r.ID, Name: r.Name, Type: r.Type, SourceURL: r.SourceURL, Frozen: r.Frozen, SyncMode: r.SyncMode, CreatedAt: r.CreatedAt, } }