100 lines
2.5 KiB
Go
100 lines
2.5 KiB
Go
package httpapi
|
|||
|
|
|
||
|
|
import (
|
||
|
|
"errors"
|
||
|
|
"net/http"
|
||
|
|
"strings"
|
||
|
|
"time"
|
||
|
|
|
||
|
|
"github.com/descrybe/descrybe-v2/apps/api/internal/support"
|
||
|
|
"github.com/go-chi/chi/v5"
|
||
|
|
"github.com/google/uuid"
|
||
|
|
)
|
||
|
|
|
||
|
|
func (s *Server) handleSubmitSupportCSAT(w http.ResponseWriter, r *http.Request) {
|
||
|
|
if s.Support == nil {
|
||
|
|
Error(w, http.StatusServiceUnavailable, "support unavailable")
|
||
|
|
return
|
||
|
|
}
|
||
|
|
cid, ok := CompanyIDFromContext(r.Context())
|
||
|
|
if !ok {
|
||
|
|
Error(w, http.StatusUnauthorized, "unauthorized")
|
||
|
|
return
|
||
|
|
}
|
||
|
|
uid, ok := UserIDFromContext(r.Context())
|
||
|
|
if !ok {
|
||
|
|
Error(w, http.StatusUnauthorized, "unauthorized")
|
||
|
|
return
|
||
|
|
}
|
||
|
|
id, err := uuid.Parse(chi.URLParam(r, "id"))
|
||
|
|
if err != nil {
|
||
|
|
Error(w, http.StatusBadRequest, "invalid id")
|
||
|
|
return
|
||
|
|
}
|
||
|
|
var body support.CSATInput
|
||
|
|
if err := DecodeJSON(r, &body); err != nil {
|
||
|
|
Error(w, http.StatusBadRequest, "invalid json")
|
||
|
|
return
|
||
|
|
}
|
||
|
|
item, err := s.Support.SubmitCSAT(r.Context(), cid, uid, id, body)
|
||
|
|
if errors.Is(err, support.ErrNotFound) {
|
||
|
|
Error(w, http.StatusNotFound, "not found")
|
||
|
|
return
|
||
|
|
}
|
||
|
|
if errors.Is(err, support.ErrAlreadyRated) {
|
||
|
|
Error(w, http.StatusConflict, "already rated")
|
||
|
|
return
|
||
|
|
}
|
||
|
|
if err != nil {
|
||
|
|
ClientOrLog(w, http.StatusBadRequest, "could not submit rating", err, support.ClientError)
|
||
|
|
return
|
||
|
|
}
|
||
|
|
JSON(w, http.StatusCreated, item)
|
||
|
|
}
|
||
|
|
|
||
|
|
func (s *Server) handleAdminSupportCSATAggregate(w http.ResponseWriter, r *http.Request) {
|
||
|
|
if s.Support == nil {
|
||
|
|
JSON(w, http.StatusOK, support.CSATAggregate{
|
||
|
|
Total: 0,
|
||
|
|
Average: 0,
|
||
|
|
Distribution: map[string]int64{"1": 0, "2": 0, "3": 0, "4": 0, "5": 0},
|
||
|
|
})
|
||
|
|
return
|
||
|
|
}
|
||
|
|
var from, to *time.Time
|
||
|
|
if raw := strings.TrimSpace(r.URL.Query().Get("from")); raw != "" {
|
||
|
|
t, err := time.Parse(time.RFC3339, raw)
|
||
|
|
if err != nil {
|
||
|
|
Error(w, http.StatusBadRequest, "invalid from (use RFC3339)")
|
||
|
|
return
|
||
|
|
}
|
||
|
|
t = t.UTC()
|
||
|
|
from = &t
|
||
|
|
}
|
||
|
|
if raw := strings.TrimSpace(r.URL.Query().Get("to")); raw != "" {
|
||
|
|
t, err := time.Parse(time.RFC3339, raw)
|
||
|
|
if err != nil {
|
||
|
|
Error(w, http.StatusBadRequest, "invalid to (use RFC3339)")
|
||
|
|
return
|
||
|
|
}
|
||
|
|
t = t.UTC()
|
||
|
|
to = &t
|
||
|
|
}
|
||
|
|
agg, err := s.Support.AggregateCSAT(r.Context(), from, to)
|
||
|
|
if err != nil {
|
||
|
|
if support.IsMissingRelation(err) {
|
||
|
|
JSON(w, http.StatusOK, support.CSATAggregate{
|
||
|
|
Total: 0,
|
||
|
|
Average: 0,
|
||
|
|
Distribution: map[string]int64{"1": 0, "2": 0, "3": 0, "4": 0, "5": 0},
|
||
|
|
From: from,
|
||
|
|
To: to,
|
||
|
|
})
|
||
|
|
return
|
||
|
|
}
|
||
|
|
LogAndError(w, http.StatusInternalServerError, "could not load csat aggregate", err)
|
||
|
|
return
|
||
|
|
}
|
||
|
|
JSON(w, http.StatusOK, agg)
|
||
|
|
}
|