package v1 import ( "net/http" "github.com/gin-gonic/gin" "github.com/gochat/gochat/internal/service" "github.com/gochat/gochat/pkg/response" ) // PushSubscriptionHandler handles push notification token registration/removal. // Reference: Chatwoot PushSubscription controller + P2B M8 spec type PushSubscriptionHandler struct { pushSubscriptionService *service.PushSubscriptionService } // NewPushSubscriptionHandler creates a new PushSubscription handler with injected service. func NewPushSubscriptionHandler(pushSubscriptionService *service.PushSubscriptionService) *PushSubscriptionHandler { return &PushSubscriptionHandler{pushSubscriptionService: pushSubscriptionService} } // List returns all push tokens for the current user. // GET /api/v1/push_subscriptions func (h *PushSubscriptionHandler) List(c *gin.Context) { if h.pushSubscriptionService == nil { response.AbortWithStatusError(c, http.StatusServiceUnavailable, response.ErrInternal, "Push subscription service not available") return } userID := getUserID(c) tokens, err := h.pushSubscriptionService.ListPushTokens(c.Request.Context(), userID) if err != nil { response.AbortWithStatusError(c, http.StatusInternalServerError, response.ErrInternal, "Failed to fetch push subscriptions") return } response.OK(c, gin.H{"push_subscriptions": tokens}) } // Create registers a new push token for the current user. // POST /api/v1/push_subscriptions func (h *PushSubscriptionHandler) Create(c *gin.Context) { if h.pushSubscriptionService == nil { response.AbortWithStatusError(c, http.StatusServiceUnavailable, response.ErrInternal, "Push subscription service not available") return } userID := getUserID(c) var req struct { Token string `json:"token" binding:"required"` Platform string `json:"platform"` DeviceID string `json:"device_id"` P256DH string `json:"p256dh"` // Web Push: client ECDH public key Auth string `json:"auth"` // Web Push: client auth secret } if err := c.ShouldBindJSON(&req); err != nil { response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrBadRequest, "Invalid request: token is required") return } token, err := h.pushSubscriptionService.RegisterPushToken(c.Request.Context(), userID, req.Token, req.Platform, req.DeviceID, req.P256DH, req.Auth) if err != nil { response.AbortWithStatusError(c, http.StatusInternalServerError, response.ErrInternal, "Failed to register push subscription") return } response.Created(c, token) } // Delete removes a push token by ID. // DELETE /api/v1/push_subscriptions/:id func (h *PushSubscriptionHandler) Delete(c *gin.Context) { if h.pushSubscriptionService == nil { response.AbortWithStatusError(c, http.StatusServiceUnavailable, response.ErrInternal, "Push subscription service not available") return } id, err := parseUintParam(c, "id") if err != nil { response.AbortWithStatusError(c, http.StatusBadRequest, response.ErrBadRequest, "Invalid push subscription ID") return } if err := h.pushSubscriptionService.RemovePushToken(c.Request.Context(), id); err != nil { response.AbortWithStatusError(c, http.StatusInternalServerError, response.ErrInternal, "Failed to remove push subscription") return } response.NoContent(c) }