package handler import ( "net/http" "bugulma/backend/internal/domain" "bugulma/backend/internal/service" "github.com/gin-gonic/gin" ) // ProposalHandler handles proposal-related HTTP requests type ProposalHandler struct { proposalService *service.ProposalService } // NewProposalHandler creates a new proposal handler func NewProposalHandler(proposalService *service.ProposalService) *ProposalHandler { return &ProposalHandler{ proposalService: proposalService, } } // GetAll returns all proposals with optional filters func (h *ProposalHandler) GetAll(c *gin.Context) { ctx := c.Request.Context() proposals, err := h.proposalService.GetAll(ctx) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to get proposals"}) return } c.JSON(http.StatusOK, gin.H{ "proposals": proposals, "count": len(proposals), }) } // GetByID returns a proposal by ID func (h *ProposalHandler) GetByID(c *gin.Context) { id := c.Param("id") if id == "" { c.JSON(http.StatusBadRequest, gin.H{"error": "Proposal ID is required"}) return } ctx := c.Request.Context() proposal, err := h.proposalService.GetByID(ctx, id) if err != nil { c.JSON(http.StatusNotFound, gin.H{"error": "Proposal not found"}) return } c.JSON(http.StatusOK, proposal) } // GetByOrganizationID returns proposals for an organization func (h *ProposalHandler) GetByOrganizationID(c *gin.Context) { orgID := c.Param("orgId") if orgID == "" { c.JSON(http.StatusBadRequest, gin.H{"error": "Organization ID is required"}) return } ctx := c.Request.Context() proposals, err := h.proposalService.GetByOrganizationID(ctx, orgID) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to get proposals"}) return } c.JSON(http.StatusOK, proposals) } // Create creates a new proposal func (h *ProposalHandler) Create(c *gin.Context) { var req struct { FromOrgID string `json:"from_org_id" binding:"required"` ToOrgID string `json:"to_org_id" binding:"required"` ResourceID string `json:"resource_id" binding:"required"` ResourceType string `json:"resource_type" binding:"required"` ResourceName string `json:"resource_name"` Message string `json:"message"` } if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } ctx := c.Request.Context() proposalReq := service.CreateProposalRequest{ FromOrgID: req.FromOrgID, ToOrgID: req.ToOrgID, ResourceID: req.ResourceID, ResourceType: domain.ResourceDirection(req.ResourceType), ResourceName: req.ResourceName, Message: req.Message, } proposal, err := h.proposalService.Create(ctx, proposalReq) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create proposal"}) return } c.JSON(http.StatusCreated, proposal) } // UpdateStatus updates proposal status func (h *ProposalHandler) UpdateStatus(c *gin.Context) { id := c.Param("id") if id == "" { c.JSON(http.StatusBadRequest, gin.H{"error": "Proposal ID is required"}) return } var req struct { Status string `json:"status" binding:"required"` } if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } // Validate status var status domain.ProposalStatus switch req.Status { case "pending": status = domain.ProposalStatusPending case "accepted": status = domain.ProposalStatusAccepted case "rejected": status = domain.ProposalStatusRejected default: c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid status"}) return } ctx := c.Request.Context() err := h.proposalService.UpdateStatus(ctx, id, status) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to update proposal status"}) return } c.JSON(http.StatusOK, gin.H{"message": "Proposal status updated successfully"}) }