package handler import ( "encoding/json" "net/http" "strconv" "gitea.gabilandia.com/gabdlr/agenda-web-go/internal/models" "gitea.gabilandia.com/gabdlr/agenda-web-go/internal/repository" ) type ContactHandler struct { repository repository.Repository[models.Contact] } const required_field = "is required" const invalid_id = "Invalid ID" func HandleContacts(mux *http.ServeMux, repo repository.Repository[models.Contact]) { ch := &ContactHandler{repository: repo} routes := []Route{ {"GET /contacts", ch.getAll}, {"GET /contacts/{id}", ch.getByID}, {"POST /contacts", ch.create}, {"PUT /contacts/{id}", ch.update}, {"DELETE /contacts/{id}", ch.delete}, } NewBaseHandler(mux, routes) } // GetAll godoc // @Summary Get all contacts // @Description Get a list of all contacts // @Tags contacts // @Accept json // @Produce json // @Success 200 {object} APIResponse{data=[]models.Contact} // @Failure 500 {object} APIResponse // @Router /contacts [get] func (h *ContactHandler) getAll(w http.ResponseWriter, r *http.Request) { contacts, err := h.repository.GetAll() if err != nil { InternalError(w, err) return } JSONSuccess(w, contacts, "Contact list retrieved successfully", http.StatusOK) } // GetByID godoc // @Summary Get a contact by ID // @Description Get a single contact by its ID // @Tags contacts // @Accept json // @Produce json // @Param id path int true "Contact ID" // @Success 200 {object} APIResponse{data=models.Contact} // @Failure 400 {object} APIResponse // @Failure 404 {object} APIResponse // @Failure 500 {object} APIResponse // @Router /contacts/{id} [get] func (h *ContactHandler) getByID(w http.ResponseWriter, r *http.Request) { id, err := strconv.Atoi(r.PathValue("id")) if err != nil { BadRequest(w, ErrInvalidFormat, invalid_id) return } contact, err := h.repository.GetByID(id) if err != nil { InternalError(w, err) return } if contact == nil { NotFound(w, ErrNotFound, "Contact not found") return } JSONSuccess(w, contact, "Contact retrieved successfully", http.StatusOK) } // Create godoc // @Summary Create a new contact // @Description Create a new contact with the provided data // @Tags contacts // @Accept json // @Produce json // @Param contact body models.Contact true "Contact object" // @Success 201 {object} APIResponse{data=models.Contact} // @Failure 400 {object} APIResponse // @Failure 500 {object} APIResponse // @Router /contacts [post] func (h *ContactHandler) create(w http.ResponseWriter, r *http.Request) { var contact models.Contact if err := json.NewDecoder(r.Body).Decode(&contact); err != nil { BadRequest(w, ErrInvalidJSON, "Error parsing the contact") return } if contact.Name == "" { err := ErrMissingRequired err.Field = "name" BadRequest(w, err, RequiredFieldErr("name")) return } if contact.Company == "" { err := ErrMissingRequired err.Field = "company" BadRequest(w, err, RequiredFieldErr("company")) return } if contact.Phone == "" { err := ErrMissingRequired err.Field = "phone" BadRequest(w, err, RequiredFieldErr("phone")) return } id, err := h.repository.Create(&contact) if err != nil { InternalError(w, err) return } contact.ID = int(id) JSONSuccess(w, contact, "Contact created successfully", http.StatusCreated) } // Update godoc // @Summary Update a contact // @Description Update an existing contact by ID // @Tags contacts // @Accept json // @Produce json // @Param id path int true "Contact ID" // @Param contact body models.Contact true "Contact object" // @Success 200 {object} APIResponse // @Failure 400 {object} APIResponse // @Failure 404 {object} APIResponse // @Failure 500 {object} APIResponse // @Router /contacts/{id} [put] func (h *ContactHandler) update(w http.ResponseWriter, r *http.Request) { id, err := strconv.Atoi(r.PathValue("id")) if err != nil { BadRequest(w, ErrInvalidFormat, invalid_id) return } var contact models.Contact if err := json.NewDecoder(r.Body).Decode(&contact); err != nil { BadRequest(w, ErrInvalidJSON, "Error parsing the contact") return } contact.ID = id updateErr := h.repository.Update(&contact) if updateErr != nil { InternalError(w, updateErr) return } JSONSuccess(w, nil, "Contact updated successfully", http.StatusOK) } // Delete godoc // @Summary Delete a contact // @Description Delete a contact by ID // @Tags contacts // @Accept json // @Produce json // @Param id path int true "Contact ID" // @Success 200 {object} APIResponse // @Failure 400 {object} APIResponse // @Failure 404 {object} APIResponse // @Failure 500 {object} APIResponse // @Router /contacts/{id} [delete] func (h *ContactHandler) delete(w http.ResponseWriter, r *http.Request) { id, err := strconv.Atoi(r.PathValue("id")) if err != nil { BadRequest(w, ErrInvalidFormat, invalid_id) return } rowsAffected, err := h.repository.Delete(id) if err != nil { InternalError(w, err) return } if rowsAffected == 0 { BadRequest(w, ErrNotFound, "Contact not found") return } JSONSuccess(w, nil, "Contact deleted successfully", http.StatusOK) }