Files
gochat/internal/handler/api/v1/inbox_member_handler.go
T
2026-06-04 15:44:48 +08:00

154 lines
4.6 KiB
Go

package v1
import (
"net/http"
"github.com/gin-gonic/gin"
"github.com/gochat/gochat/internal/service"
)
// InboxMemberHandler handles inbox member (seat assignment) API endpoints.
// Reference: Chatwoot app/controllers/api/v1/inbox_members_controller.rb
// Routes manage which agents are assigned to which inboxes (seat assignment).
type InboxMemberHandler struct {
svc *service.InboxMemberService
}
// NewInboxMemberHandler creates a new InboxMemberHandler.
func NewInboxMemberHandler(svc *service.InboxMemberService) *InboxMemberHandler {
return &InboxMemberHandler{svc: svc}
}
// ListMembers retrieves all agents assigned to an inbox.
// GET /api/v1/accounts/:id/inboxes/:inbox_id/members
// Reference: Chatwoot inbox_members#index
func (h *InboxMemberHandler) ListMembers(c *gin.Context) {
inboxID, err := parseUintParam(c, "inbox_id")
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid inbox id"})
return
}
members, svcErr := h.svc.ListByInbox(c.Request.Context(), inboxID)
if svcErr != nil {
c.JSON(http.StatusUnprocessableEntity, gin.H{"error": "failed to list inbox members"})
return
}
c.JSON(http.StatusOK, gin.H{
"members": members,
"meta": gin.H{"count": len(members)},
})
}
// AddMember assigns an agent to an inbox (seat assignment).
// POST /api/v1/accounts/:id/inboxes/:inbox_id/members
// Reference: Chatwoot inbox_members#create
func (h *InboxMemberHandler) AddMember(c *gin.Context) {
inboxID, err := parseUintParam(c, "inbox_id")
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid inbox id"})
return
}
var req service.AddMemberRequest
if bindErr := c.ShouldBindJSON(&req); bindErr != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": bindErr.Error()})
return
}
// Override inbox_id from URL path parameter
req.InboxID = inboxID
member, svcErr := h.svc.AddMember(c.Request.Context(), req)
if svcErr != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": svcErr.Error()})
return
}
c.JSON(http.StatusCreated, member)
}
// RemoveMember removes an agent from an inbox (unassign seat).
// DELETE /api/v1/accounts/:id/inboxes/:inbox_id/members/:user_id
// Reference: Chatwoot inbox_members#destroy
func (h *InboxMemberHandler) RemoveMember(c *gin.Context) {
inboxID, err := parseUintParam(c, "inbox_id")
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid inbox id"})
return
}
userID, err := parseUintParam(c, "user_id")
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid user id"})
return
}
if svcErr := h.svc.RemoveMember(c.Request.Context(), inboxID, userID); svcErr != nil {
c.JSON(http.StatusUnprocessableEntity, gin.H{"error": "failed to remove member"})
return
}
c.JSON(http.StatusOK, gin.H{"inbox_id": inboxID, "user_id": userID, "removed": true})
}
// UpdateMember updates a member's role or availability status.
// PATCH /api/v1/accounts/:id/inboxes/:inbox_id/members/:user_id
// Reference: Chatwoot inbox_members#update
func (h *InboxMemberHandler) UpdateMember(c *gin.Context) {
inboxID, err := parseUintParam(c, "inbox_id")
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid inbox id"})
return
}
userID, err := parseUintParam(c, "user_id")
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid user id"})
return
}
var req service.UpdateMemberRequest
if bindErr := c.ShouldBindJSON(&req); bindErr != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": bindErr.Error()})
return
}
member, svcErr := h.svc.UpdateMember(c.Request.Context(), inboxID, userID, req)
if svcErr != nil {
c.JSON(http.StatusUnprocessableEntity, gin.H{"error": "failed to update member"})
return
}
c.JSON(http.StatusOK, member)
}
// UpdateMultiple replaces all members of an inbox with a new set of user IDs (batch seat assignment).
// PATCH /api/v1/accounts/:id/inboxes/:inbox_id/members/update_multiple
// Reference: Chatwoot inbox_members#update (batch replace)
func (h *InboxMemberHandler) UpdateMultiple(c *gin.Context) {
inboxID, err := parseUintParam(c, "inbox_id")
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid inbox id"})
return
}
var req service.UpdateMultipleRequest
if bindErr := c.ShouldBindJSON(&req); bindErr != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": bindErr.Error()})
return
}
req.InboxID = inboxID
members, svcErr := h.svc.UpdateMultiple(c.Request.Context(), req)
if svcErr != nil {
c.JSON(http.StatusUnprocessableEntity, gin.H{"error": "failed to update members"})
return
}
c.JSON(http.StatusOK, gin.H{
"members": members,
"meta": gin.H{"count": len(members)},
})
}