86 lines
2.1 KiB
Go
86 lines
2.1 KiB
Go
package handler
|
|
|
|
import (
|
|
"net/http"
|
|
"strconv"
|
|
|
|
"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/service"
|
|
)
|
|
|
|
type ProfileHandler struct {
|
|
svc *service.ProfileService
|
|
log *zap.Logger
|
|
}
|
|
|
|
func NewProfileHandler(svc *service.ProfileService, log *zap.Logger) *ProfileHandler {
|
|
return &ProfileHandler{svc: svc, log: log}
|
|
}
|
|
|
|
// Get handles GET /profiles/:id.
|
|
func (h *ProfileHandler) Get(w http.ResponseWriter, r *http.Request) {
|
|
id, err := parseProfileID(r)
|
|
if err != nil {
|
|
writeError(w, err)
|
|
return
|
|
}
|
|
ws := middleware.WorkspaceFromCtx(r.Context())
|
|
p, err := h.svc.Get(r.Context(), ws, id)
|
|
if err != nil {
|
|
writeError(w, err)
|
|
return
|
|
}
|
|
writeJSON(w, http.StatusOK, p)
|
|
}
|
|
|
|
// Timeline handles GET /profiles/:id/events.
|
|
func (h *ProfileHandler) Timeline(w http.ResponseWriter, r *http.Request) {
|
|
id, err := parseProfileID(r)
|
|
if err != nil {
|
|
writeError(w, err)
|
|
return
|
|
}
|
|
limit, offset := parsePagination(r, 100, 1000)
|
|
|
|
ws := middleware.WorkspaceFromCtx(r.Context())
|
|
res, err := h.svc.Timeline(r.Context(), ws, id, limit, offset)
|
|
if err != nil {
|
|
writeError(w, err)
|
|
return
|
|
}
|
|
writeJSON(w, http.StatusOK, res)
|
|
}
|
|
|
|
func parseProfileID(r *http.Request) (string, error) {
|
|
raw := chi.URLParam(r, "id")
|
|
if raw == "" {
|
|
return "", apperr.BadRequest("missing profile id", "id", nil)
|
|
}
|
|
if _, err := uuid.Parse(raw); err != nil {
|
|
return "", apperr.BadRequest("profile id must be uuid", "id", err)
|
|
}
|
|
return raw, nil
|
|
}
|
|
|
|
// parsePagination reads ?limit & ?offset with bounds. Invalid values fall back
|
|
// to the defaults rather than erroring -- the endpoints are GET, not strict.
|
|
func parsePagination(r *http.Request, def, max int) (limit, offset int) {
|
|
limit = def
|
|
if v := r.URL.Query().Get("limit"); v != "" {
|
|
if n, err := strconv.Atoi(v); err == nil && n > 0 && n <= max {
|
|
limit = n
|
|
}
|
|
}
|
|
if v := r.URL.Query().Get("offset"); v != "" {
|
|
if n, err := strconv.Atoi(v); err == nil && n >= 0 {
|
|
offset = n
|
|
}
|
|
}
|
|
return
|
|
}
|