174 lines
5.1 KiB
Go
174 lines
5.1 KiB
Go
package httpapi
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"inbox/internal/base/httpx"
|
|
"inbox/internal/domain/topic"
|
|
"inbox/internal/domain/workspace"
|
|
)
|
|
|
|
func (h *Handler) dashboardMessages(w http.ResponseWriter, r *http.Request) {
|
|
h.writeWorkspacePayload(w, r, http.StatusOK, func(ws workspace.Workspace) (any, error) {
|
|
return h.Dashboard.Messages(r.Context(), ws)
|
|
})
|
|
}
|
|
|
|
func (h *Handler) dashboardTopics(w http.ResponseWriter, r *http.Request) {
|
|
h.writeWorkspacePayload(w, r, http.StatusOK, func(ws workspace.Workspace) (any, error) {
|
|
return h.Dashboard.Topics(r.Context(), ws)
|
|
})
|
|
}
|
|
|
|
func (h *Handler) dashboardTopicRecords(w http.ResponseWriter, r *http.Request) {
|
|
spaceFilter := strings.TrimSpace(r.URL.Query().Get("space"))
|
|
h.writeWorkspacePayload(w, r, http.StatusOK, func(ws workspace.Workspace) (any, error) {
|
|
return h.Dashboard.TopicRecords(r.Context(), ws, spaceFilter)
|
|
})
|
|
}
|
|
|
|
func (h *Handler) dashboardSpaceTopics(w http.ResponseWriter, r *http.Request) {
|
|
space, err := parseTopicSpace(r.PathValue("space"))
|
|
if err != nil {
|
|
httpx.WriteError(w, http.StatusBadRequest, err.Error())
|
|
return
|
|
}
|
|
h.writeWorkspacePayload(w, r, http.StatusOK, func(ws workspace.Workspace) (any, error) {
|
|
return h.Dashboard.SpaceTopics(r.Context(), ws, space)
|
|
})
|
|
}
|
|
|
|
func (h *Handler) dashboardSpaceMessages(w http.ResponseWriter, r *http.Request) {
|
|
space, err := parseTopicSpace(r.PathValue("space"))
|
|
if err != nil {
|
|
httpx.WriteError(w, http.StatusBadRequest, err.Error())
|
|
return
|
|
}
|
|
topicSlug := strings.TrimSpace(r.URL.Query().Get("topic"))
|
|
if topicSlug == "" {
|
|
httpx.WriteError(w, http.StatusBadRequest, "topic is required")
|
|
return
|
|
}
|
|
h.writeWorkspacePayload(w, r, http.StatusOK, func(ws workspace.Workspace) (any, error) {
|
|
return h.Dashboard.SpaceMessages(r.Context(), ws, space, topicSlug)
|
|
})
|
|
}
|
|
|
|
func (h *Handler) dashboardDispatch(w http.ResponseWriter, r *http.Request) {
|
|
h.writeWorkspacePayload(w, r, http.StatusOK, func(ws workspace.Workspace) (any, error) {
|
|
return h.Dashboard.Dispatch(r.Context(), ws)
|
|
})
|
|
}
|
|
|
|
func (h *Handler) dashboardDispatchLive(w http.ResponseWriter, r *http.Request) {
|
|
topicSlug := strings.TrimSpace(r.URL.Query().Get("topic"))
|
|
roleName := strings.TrimSpace(r.URL.Query().Get("role"))
|
|
if topicSlug == "" || roleName == "" {
|
|
httpx.WriteError(w, http.StatusBadRequest, "topic and role are required")
|
|
return
|
|
}
|
|
afterSeq, err := parseIntQuery(r, "offset")
|
|
if err != nil {
|
|
httpx.WriteError(w, http.StatusBadRequest, "offset must be an integer")
|
|
return
|
|
}
|
|
h.writeWorkspacePayload(w, r, http.StatusOK, func(ws workspace.Workspace) (any, error) {
|
|
return h.Dashboard.DispatchLive(r.Context(), ws, topicSlug, roleName, afterSeq)
|
|
})
|
|
}
|
|
|
|
func (h *Handler) dashboardRoles(w http.ResponseWriter, r *http.Request) {
|
|
ws, ok := h.optionalWorkspace(w, r)
|
|
if !ok {
|
|
return
|
|
}
|
|
payload, err := h.Dashboard.Roles(r.Context(), ws)
|
|
writePayload(w, http.StatusOK, payload, err)
|
|
}
|
|
|
|
func (h *Handler) dashboardWorkflowBoard(w http.ResponseWriter, r *http.Request) {
|
|
activeTopic := strings.TrimSpace(r.URL.Query().Get("topic"))
|
|
h.writeWorkspacePayload(w, r, http.StatusOK, func(ws workspace.Workspace) (any, error) {
|
|
return h.Dashboard.WorkflowBoard(r.Context(), ws, activeTopic)
|
|
})
|
|
}
|
|
|
|
func (h *Handler) resolveWorkspace(r *http.Request) (workspace.Workspace, error) {
|
|
return h.Workspaces.Resolve(
|
|
r.Context(),
|
|
r.URL.Query().Get("workspace_id"),
|
|
firstNonEmpty(r.URL.Query().Get("workspace"), r.URL.Query().Get("workspace_slug")),
|
|
)
|
|
}
|
|
|
|
func (h *Handler) requireWorkspace(w http.ResponseWriter, r *http.Request) (workspace.Workspace, bool) {
|
|
ws, err := h.resolveWorkspace(r)
|
|
if err != nil {
|
|
writeStoreError(w, err)
|
|
return workspace.Workspace{}, false
|
|
}
|
|
return ws, true
|
|
}
|
|
|
|
func (h *Handler) optionalWorkspace(w http.ResponseWriter, r *http.Request) (*workspace.Workspace, bool) {
|
|
if strings.TrimSpace(firstNonEmpty(
|
|
r.URL.Query().Get("workspace_id"),
|
|
r.URL.Query().Get("workspace"),
|
|
r.URL.Query().Get("workspace_slug"),
|
|
)) == "" {
|
|
return nil, true
|
|
}
|
|
ws, err := h.resolveWorkspace(r)
|
|
if err != nil {
|
|
writeStoreError(w, err)
|
|
return nil, false
|
|
}
|
|
return &ws, true
|
|
}
|
|
|
|
func (h *Handler) writeWorkspacePayload(w http.ResponseWriter, r *http.Request, status int, load func(workspace.Workspace) (any, error)) {
|
|
ws, ok := h.requireWorkspace(w, r)
|
|
if !ok {
|
|
return
|
|
}
|
|
payload, err := load(ws)
|
|
writePayload(w, status, payload, err)
|
|
}
|
|
|
|
func writePayload(w http.ResponseWriter, status int, payload any, err error) {
|
|
if err != nil {
|
|
writeStoreError(w, err)
|
|
return
|
|
}
|
|
httpx.WriteJSON(w, status, payload)
|
|
}
|
|
|
|
func parseTopicSpace(value string) (topic.Space, error) {
|
|
switch topic.Space(value) {
|
|
case topic.SpaceClarify, topic.SpaceWorkflow:
|
|
return topic.Space(value), nil
|
|
default:
|
|
return "", fmt.Errorf("invalid space %q", value)
|
|
}
|
|
}
|
|
|
|
func parseIntQuery(r *http.Request, key string) (int, error) {
|
|
value := strings.TrimSpace(r.URL.Query().Get(key))
|
|
if value == "" {
|
|
return 0, nil
|
|
}
|
|
return strconv.Atoi(value)
|
|
}
|
|
|
|
func firstNonEmpty(values ...string) string {
|
|
for _, value := range values {
|
|
if strings.TrimSpace(value) != "" {
|
|
return value
|
|
}
|
|
}
|
|
return ""
|
|
}
|