package api import ( "net/http" "github.com/gin-gonic/gin" ) // shareCreateRequest is the body for POST /gardens/:id/shares: the recipient's // exact account email and the role to grant (viewer|editor). type shareCreateRequest struct { Email string `json:"email" binding:"required"` Role string `json:"role" binding:"required"` } // shareUpdateRequest is the body for PATCH /gardens/:id/shares/:userId. type shareUpdateRequest struct { Role string `json:"role" binding:"required"` } func (h *handlers) listShares(c *gin.Context) { gardenID, ok := parseIDParam(c, "id") if !ok { return } shares, err := h.svc.ListShares(c.Request.Context(), mustActor(c).ID, gardenID) if err != nil { writeServiceError(c, err) return } c.JSON(http.StatusOK, shares) } func (h *handlers) addShare(c *gin.Context) { gardenID, ok := parseIDParam(c, "id") if !ok { return } var req shareCreateRequest if err := c.ShouldBindJSON(&req); err != nil { writeAPIError(c, http.StatusBadRequest, "INVALID_INPUT", "an email and a role are required") return } sh, err := h.svc.AddShare(c.Request.Context(), mustActor(c).ID, gardenID, req.Email, req.Role) if err != nil { writeServiceError(c, err) return } c.JSON(http.StatusCreated, sh) } func (h *handlers) updateShare(c *gin.Context) { gardenID, ok := parseIDParam(c, "id") if !ok { return } userID, ok := parseIDParam(c, "userId") if !ok { return } var req shareUpdateRequest if err := c.ShouldBindJSON(&req); err != nil { writeAPIError(c, http.StatusBadRequest, "INVALID_INPUT", "a role is required") return } sh, err := h.svc.UpdateShareRole(c.Request.Context(), mustActor(c).ID, gardenID, userID, req.Role) if err != nil { writeServiceError(c, err) return } c.JSON(http.StatusOK, sh) } func (h *handlers) removeShare(c *gin.Context) { gardenID, ok := parseIDParam(c, "id") if !ok { return } userID, ok := parseIDParam(c, "userId") if !ok { return } if err := h.svc.RemoveShare(c.Request.Context(), mustActor(c).ID, gardenID, userID); err != nil { writeServiceError(c, err) return } c.Status(http.StatusNoContent) }