Files
kandev/apps/backend/internal/runtimeflags/handlers.go
T
João Salavisa 481359ddb2 feat(auth): organization units, tenancy, roles and scopes for team access (#2919)
Co-authored-by: Kandev Agent <agent@kandev.dev>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-05 13:40:43 +00:00

63 lines
1.6 KiB
Go

package runtimeflags
import (
"errors"
"io"
"net/http"
"github.com/gin-gonic/gin"
"github.com/kandev/kandev/internal/authz"
)
type Handler struct {
svc *Service
}
func RegisterRoutes(router gin.IRouter, svc *Service) {
h := &Handler{svc: svc}
api := router.Group("/api/v1/runtime-flags")
api.GET("", h.list)
// Flag overrides are install-wide; only admins may change them. With
// auth disabled the synthetic identity is an admin (no behavior change).
api.PATCH("/:key", authz.RequireOrgScope(authz.ScopeOrgSettingsManage), h.patch)
}
func (h *Handler) list(c *gin.Context) {
states, err := h.svc.ListStates(c.Request.Context())
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to read runtime flags"})
return
}
c.JSON(http.StatusOK, gin.H{"flags": states})
}
type patchRequest struct {
Override *bool `json:"override"`
}
func (h *Handler) patch(c *gin.Context) {
var req patchRequest
if err := c.ShouldBindJSON(&req); err != nil {
if !errors.Is(err, io.EOF) {
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid runtime flag payload"})
return
}
}
states, err := h.svc.SetOverride(c.Request.Context(), c.Param("key"), req.Override)
if err != nil {
status := http.StatusInternalServerError
msg := "failed to update runtime flag"
if errors.Is(err, ErrEnvLocked) {
status = http.StatusConflict
msg = "runtime flag is controlled by environment"
} else if errors.Is(err, ErrUnknownFlag) {
status = http.StatusNotFound
msg = "runtime flag not found"
}
c.JSON(status, gin.H{"error": msg})
return
}
c.JSON(http.StatusOK, gin.H{"flags": states})
}