Files
Productier/apps/backend/internal/httpapi/integration_routes.go
T
Tomas Dvorak 3cb40adb23 first commit
2026-04-10 12:04:09 +02:00

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})
})
}