/
DexScen
/
ProjectPOH
Обзор
Документация
Войти
/
DexScen
/
ProjectPOH
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
backend/internal/posts/handler.go
179 строк
5 KB
Александр
changes
14 май 2026, 15:02
14 май 2026, 15:02
3f3feb2
Код
Авторство
О чём код?
package posts import ( "errors" "net/http" "strings" "github.com/DexScen/projectpoh/backend/internal/auth" "github.com/DexScen/projectpoh/backend/internal/domainerr" "github.com/DexScen/projectpoh/backend/internal/httpapi" "github.com/DexScen/projectpoh/backend/internal/middleware" ) type Handler struct { service *Service authService *auth.Service } func NewHandler(service *Service, authService *auth.Service) *Handler { return &Handler{service: service, authService: authService} } func (h *Handler) RegisterRoutes(mux *http.ServeMux) { mux.HandleFunc("GET /api/v1/posts", h.list) mux.Handle("POST /api/v1/posts", middleware.RequireAuth(h.authService)(http.HandlerFunc(h.create))) mux.HandleFunc("GET /api/v1/posts/{id}", h.getByID) mux.Handle("PATCH /api/v1/posts/{id}", middleware.RequireAuth(h.authService)(http.HandlerFunc(h.update))) mux.Handle("DELETE /api/v1/posts/{id}", middleware.RequireAuth(h.authService)(http.HandlerFunc(h.delete))) } func (h *Handler) list(w http.ResponseWriter, r *http.Request) { limit, offset, err := httpapi.ParsePagination(r, 20, 100) if err != nil { httpapi.WriteError(w, http.StatusBadRequest, err) return } opts := ListOptions{ Limit: limit, Offset: offset, Search: strings.TrimSpace(r.URL.Query().Get("search")), Sort: strings.TrimSpace(r.URL.Query().Get("sort")), Order: strings.TrimSpace(r.URL.Query().Get("order")), } items, err := h.service.List(r.Context(), opts) if err != nil { httpapi.WriteError(w, http.StatusBadRequest, err) return } httpapi.WriteJSON(w, http.StatusOK, map[string]any{ "items": items, "limit": limit, "offset": offset, }) } func (h *Handler) create(w http.ResponseWriter, r *http.Request) { principal, ok := auth.PrincipalFromContext(r.Context()) if !ok { httpapi.WriteError(w, http.StatusUnauthorized, auth.ErrInvalidToken) return } if principal.Role != "admin" { httpapi.WriteError(w, http.StatusForbidden, domainerr.ErrForbidden) return } var in CreateInput if err := httpapi.ReadJSON(r, &in); err != nil { httpapi.WriteError(w, http.StatusBadRequest, err) return } post, err := h.service.Create(r.Context(), principal.UserID, in) if err != nil { httpapi.WriteError(w, http.StatusBadRequest, err) return } httpapi.WriteJSON(w, http.StatusCreated, post) } func (h *Handler) getByID(w http.ResponseWriter, r *http.Request) { id, err := httpapi.ParsePositiveInt64(r.PathValue("id"), "id") if err != nil { httpapi.WriteError(w, http.StatusBadRequest, err) return } post, err := h.service.GetByID(r.Context(), id) if err != nil { if errors.Is(err, ErrPostNotFound) { httpapi.WriteError(w, http.StatusNotFound, err) return } httpapi.WriteError(w, http.StatusInternalServerError, err) return } httpapi.WriteJSON(w, http.StatusOK, post) } func (h *Handler) update(w http.ResponseWriter, r *http.Request) { id, err := httpapi.ParsePositiveInt64(r.PathValue("id"), "id") if err != nil { httpapi.WriteError(w, http.StatusBadRequest, err) return } principal, ok := auth.PrincipalFromContext(r.Context()) if !ok { httpapi.WriteError(w, http.StatusUnauthorized, auth.ErrInvalidToken) return } current, err := h.service.GetByID(r.Context(), id) if err != nil { httpapi.WriteError(w, http.StatusNotFound, err) return } if principal.UserID != current.UserID && principal.Role != "admin" && principal.Role != "moderator" { httpapi.WriteError(w, http.StatusForbidden, domainerr.ErrForbidden) return } var in UpdateInput if err := httpapi.ReadJSON(r, &in); err != nil { httpapi.WriteError(w, http.StatusBadRequest, err) return } updated, err := h.service.Update(r.Context(), id, in) if err != nil { if errors.Is(err, ErrPostNotFound) { httpapi.WriteError(w, http.StatusNotFound, err) return } httpapi.WriteError(w, http.StatusBadRequest, err) return } httpapi.WriteJSON(w, http.StatusOK, updated) } func (h *Handler) delete(w http.ResponseWriter, r *http.Request) { id, err := httpapi.ParsePositiveInt64(r.PathValue("id"), "id") if err != nil { httpapi.WriteError(w, http.StatusBadRequest, err) return } principal, ok := auth.PrincipalFromContext(r.Context()) if !ok { httpapi.WriteError(w, http.StatusUnauthorized, auth.ErrInvalidToken) return } current, err := h.service.GetByID(r.Context(), id) if err != nil { httpapi.WriteError(w, http.StatusNotFound, err) return } if principal.UserID != current.UserID && principal.Role != "admin" && principal.Role != "moderator" { httpapi.WriteError(w, http.StatusForbidden, domainerr.ErrForbidden) return } if err := h.service.SoftDelete(r.Context(), id); err != nil { if errors.Is(err, ErrPostNotFound) { httpapi.WriteError(w, http.StatusNotFound, err) return } httpapi.WriteError(w, http.StatusInternalServerError, err) return } httpapi.WriteJSON(w, http.StatusOK, map[string]string{"status": "deleted"}) }