mirror of
https://github.com/Dvorinka/Productier.git
synced 2026-06-03 20:13:01 +00:00
175 lines
5.2 KiB
Go
175 lines
5.2 KiB
Go
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})
|
|
})
|
|
} |