package httpapi import ( "net/http" "github.com/gin-gonic/gin" "productier/apps/backend/internal/store" ) func (s *Server) registerIntegrationRoutes(group *gin.RouterGroup) { // Integrations group.GET("/integrations", func(c *gin.Context) { workspaceSlug := c.Query("workspaceSlug") if _, ok := s.requireWorkspaceMember(c, workspaceSlug); !ok { return } c.JSON(http.StatusOK, gin.H{"data": s.store.ListIntegrations(workspaceSlug)}) }) group.POST("/integrations", func(c *gin.Context) { var input store.CreateIntegrationInput if err := c.ShouldBindJSON(&input); err != nil { s.writeStatusError(c, http.StatusBadRequest, err.Error()) return } if _, ok := s.requireWorkspaceMember(c, input.WorkspaceSlug); !ok { return } integration := s.store.CreateIntegration(input) c.JSON(http.StatusCreated, gin.H{"data": integration}) }) group.DELETE("/integrations/:integrationId", func(c *gin.Context) { integration, err := s.store.GetIntegrationByID(c.Param("integrationId")) if err != nil { s.writeStatusError(c, http.StatusNotFound, err.Error()) return } if _, ok := s.requireWorkspaceMember(c, integration.WorkspaceSlug); !ok { return } if err := s.store.DeleteIntegration(integration.ID); err != nil { s.writeStatusError(c, http.StatusInternalServerError, err.Error()) return } c.JSON(http.StatusOK, gin.H{"ok": true}) }) // Webhooks group.GET("/webhooks", func(c *gin.Context) { workspaceSlug := c.Query("workspaceSlug") if _, ok := s.requireWorkspaceMember(c, workspaceSlug); !ok { return } c.JSON(http.StatusOK, gin.H{"data": s.store.ListWebhooks(workspaceSlug)}) }) group.POST("/webhooks", func(c *gin.Context) { var input store.CreateWebhookInput if err := c.ShouldBindJSON(&input); err != nil { s.writeStatusError(c, http.StatusBadRequest, err.Error()) return } if _, ok := s.requireWorkspaceMember(c, input.WorkspaceSlug); !ok { return } webhook := s.store.CreateWebhook(input) c.JSON(http.StatusCreated, gin.H{"data": webhook}) }) group.DELETE("/webhooks/:webhookId", func(c *gin.Context) { if err := s.store.DeleteWebhook(c.Param("webhookId")); err != nil { s.writeStatusError(c, http.StatusInternalServerError, err.Error()) return } c.JSON(http.StatusOK, gin.H{"ok": true}) }) // Notifications group.GET("/notifications", func(c *gin.Context) { user := s.sessionUser(c) if user == nil { s.writeStatusError(c, http.StatusUnauthorized, "authentication required") return } limit := 50 c.JSON(http.StatusOK, gin.H{"data": s.store.ListNotifications(user.Email, limit)}) }) group.POST("/notifications/:notificationId/read", func(c *gin.Context) { if err := s.store.MarkNotificationRead(c.Param("notificationId")); err != nil { s.writeStatusError(c, http.StatusInternalServerError, err.Error()) return } c.JSON(http.StatusOK, gin.H{"ok": true}) }) group.POST("/notifications/read-all", func(c *gin.Context) { user := s.sessionUser(c) if user == nil { s.writeStatusError(c, http.StatusUnauthorized, "authentication required") return } if err := s.store.MarkAllNotificationsRead(user.Email); err != nil { s.writeStatusError(c, http.StatusInternalServerError, err.Error()) return } c.JSON(http.StatusOK, gin.H{"ok": true}) }) group.GET("/notifications/unread-count", func(c *gin.Context) { user := s.sessionUser(c) if user == nil { s.writeStatusError(c, http.StatusUnauthorized, "authentication required") return } c.JSON(http.StatusOK, gin.H{"count": s.store.UnreadNotificationCount(user.Email)}) }) // Presence group.POST("/presence", func(c *gin.Context) { var input store.UpdatePresenceInput if err := c.ShouldBindJSON(&input); err != nil { s.writeStatusError(c, http.StatusBadRequest, err.Error()) return } if _, ok := s.requireWorkspaceMember(c, input.WorkspaceSlug); !ok { return } presence := s.store.UpdatePresence(input) c.JSON(http.StatusOK, gin.H{"data": presence}) }) // Create notification (internal use) group.POST("/notifications", func(c *gin.Context) { var input store.CreateNotificationInput if err := c.ShouldBindJSON(&input); err != nil { s.writeStatusError(c, http.StatusBadRequest, err.Error()) return } if _, ok := s.requireWorkspaceMember(c, input.WorkspaceSlug); !ok { return } notification := s.store.CreateNotification(input) c.JSON(http.StatusCreated, gin.H{"data": notification}) }) group.GET("/presence", func(c *gin.Context) { workspaceSlug := c.Query("workspaceSlug") if _, ok := s.requireWorkspaceMember(c, workspaceSlug); !ok { return } entityType := c.Query("entityType") entityID := c.Query("entityId") c.JSON(http.StatusOK, gin.H{"data": s.store.ListPresence(workspaceSlug, entityType, entityID)}) }) group.DELETE("/presence", func(c *gin.Context) { workspaceSlug := c.Query("workspaceSlug") user := s.sessionUser(c) if user == nil { s.writeStatusError(c, http.StatusUnauthorized, "authentication required") return } if _, ok := s.requireWorkspaceMember(c, workspaceSlug); !ok { return } if err := s.store.ClearPresence(workspaceSlug, user.Email); err != nil { s.writeStatusError(c, http.StatusInternalServerError, err.Error()) return } c.JSON(http.StatusOK, gin.H{"ok": true}) }) }