126 lines
3.2 KiB
Go
126 lines
3.2 KiB
Go
package handler
|
|
|
|
import (
|
|
"net/http"
|
|
|
|
"github.com/go-chi/chi/v5"
|
|
"github.com/google/uuid"
|
|
"go.uber.org/zap"
|
|
|
|
"github.com/dbiz/cdp/data-layer/api/internal/apperr"
|
|
"github.com/dbiz/cdp/data-layer/api/internal/middleware"
|
|
"github.com/dbiz/cdp/data-layer/api/internal/model"
|
|
"github.com/dbiz/cdp/data-layer/api/internal/repo"
|
|
)
|
|
|
|
type SavedQueryHandler struct {
|
|
repo *repo.SavedQueryRepo
|
|
log *zap.Logger
|
|
}
|
|
|
|
func NewSavedQueryHandler(r *repo.SavedQueryRepo, log *zap.Logger) *SavedQueryHandler {
|
|
return &SavedQueryHandler{repo: r, log: log}
|
|
}
|
|
|
|
type createSavedQueryRequest struct {
|
|
Name string `json:"name" validate:"required,min=1,max=200"`
|
|
Kind string `json:"kind" validate:"required,oneof=events sql funnel retention session"`
|
|
Spec map[string]any `json:"spec" validate:"required"`
|
|
}
|
|
|
|
type updateSavedQueryRequest struct {
|
|
Name string `json:"name" validate:"required,min=1,max=200"`
|
|
Spec map[string]any `json:"spec" validate:"required"`
|
|
}
|
|
|
|
func (h *SavedQueryHandler) Create(w http.ResponseWriter, r *http.Request) {
|
|
var req createSavedQueryRequest
|
|
if err := decodeAndValidate(r, &req); err != nil {
|
|
writeError(w, err)
|
|
return
|
|
}
|
|
ws := middleware.WorkspaceFromCtx(r.Context())
|
|
q, err := h.repo.Create(r.Context(), model.SavedQuery{
|
|
WorkspaceID: ws,
|
|
Name: req.Name,
|
|
Kind: req.Kind,
|
|
Spec: req.Spec,
|
|
})
|
|
if err != nil {
|
|
writeError(w, err)
|
|
return
|
|
}
|
|
writeJSON(w, http.StatusCreated, q)
|
|
}
|
|
|
|
func (h *SavedQueryHandler) List(w http.ResponseWriter, r *http.Request) {
|
|
limit, offset := parsePagination(r, 50, 500)
|
|
ws := middleware.WorkspaceFromCtx(r.Context())
|
|
qs, err := h.repo.List(r.Context(), ws, limit, offset)
|
|
if err != nil {
|
|
writeError(w, err)
|
|
return
|
|
}
|
|
writeJSON(w, http.StatusOK, map[string]any{"items": qs, "limit": limit, "offset": offset})
|
|
}
|
|
|
|
func (h *SavedQueryHandler) Get(w http.ResponseWriter, r *http.Request) {
|
|
id, err := parseSavedQueryID(r)
|
|
if err != nil {
|
|
writeError(w, err)
|
|
return
|
|
}
|
|
ws := middleware.WorkspaceFromCtx(r.Context())
|
|
q, err := h.repo.Get(r.Context(), ws, id)
|
|
if err != nil {
|
|
writeError(w, err)
|
|
return
|
|
}
|
|
writeJSON(w, http.StatusOK, q)
|
|
}
|
|
|
|
func (h *SavedQueryHandler) Update(w http.ResponseWriter, r *http.Request) {
|
|
id, err := parseSavedQueryID(r)
|
|
if err != nil {
|
|
writeError(w, err)
|
|
return
|
|
}
|
|
var req updateSavedQueryRequest
|
|
if err := decodeAndValidate(r, &req); err != nil {
|
|
writeError(w, err)
|
|
return
|
|
}
|
|
ws := middleware.WorkspaceFromCtx(r.Context())
|
|
q, err := h.repo.Update(r.Context(), ws, id, req.Name, req.Spec)
|
|
if err != nil {
|
|
writeError(w, err)
|
|
return
|
|
}
|
|
writeJSON(w, http.StatusOK, q)
|
|
}
|
|
|
|
func (h *SavedQueryHandler) Delete(w http.ResponseWriter, r *http.Request) {
|
|
id, err := parseSavedQueryID(r)
|
|
if err != nil {
|
|
writeError(w, err)
|
|
return
|
|
}
|
|
ws := middleware.WorkspaceFromCtx(r.Context())
|
|
if err := h.repo.Delete(r.Context(), ws, id); err != nil {
|
|
writeError(w, err)
|
|
return
|
|
}
|
|
w.WriteHeader(http.StatusNoContent)
|
|
}
|
|
|
|
func parseSavedQueryID(r *http.Request) (string, error) {
|
|
raw := chi.URLParam(r, "id")
|
|
if raw == "" {
|
|
return "", apperr.BadRequest("missing query id", "id", nil)
|
|
}
|
|
if _, err := uuid.Parse(raw); err != nil {
|
|
return "", apperr.BadRequest("query id must be uuid", "id", err)
|
|
}
|
|
return raw, nil
|
|
}
|