50 lines
1.7 KiB
Go
50 lines
1.7 KiB
Go
package api
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http"
|
|
"strings"
|
|
|
|
"dana/internal/storage"
|
|
)
|
|
|
|
type newServiceRequest struct {
|
|
ParentID int64 `json:"parent_id"`
|
|
Slug string `json:"slug"`
|
|
Name string `json:"name"`
|
|
Lead string `json:"lead"`
|
|
}
|
|
|
|
// adminCreateService заводит услугу скрытой: на сайт она попадёт, когда её заполнят и включат.
|
|
func (a *API) adminCreateService(w http.ResponseWriter, r *http.Request, u *storage.AdminUser) {
|
|
var req newServiceRequest
|
|
if err := json.NewDecoder(http.MaxBytesReader(w, r.Body, 16<<10)).Decode(&req); err != nil {
|
|
fail(w, http.StatusBadRequest, "bad_request", "Некорректный запрос")
|
|
return
|
|
}
|
|
in := storage.NewService{
|
|
ParentID: req.ParentID,
|
|
Slug: strings.ToLower(strings.TrimSpace(req.Slug)),
|
|
Name: strings.TrimSpace(req.Name),
|
|
Lead: strings.TrimSpace(req.Lead),
|
|
}
|
|
switch {
|
|
case in.Name == "" || len([]rune(in.Name)) > 200:
|
|
fail(w, http.StatusUnprocessableEntity, "validation", "Укажите название услуги (до 200 символов)")
|
|
return
|
|
case in.ParentID <= 0:
|
|
fail(w, http.StatusUnprocessableEntity, "validation", "Выберите направление")
|
|
return
|
|
case !slugRE.MatchString(in.Slug) || len(in.Slug) > 100:
|
|
fail(w, http.StatusUnprocessableEntity, "validation", "Адрес — латиница, цифры и дефис, например «priem-kardiologa»")
|
|
return
|
|
}
|
|
id, err := a.store.AdminCreateService(r.Context(), in)
|
|
if err != nil {
|
|
handleErr(w, err)
|
|
return
|
|
}
|
|
a.store.Audit(r.Context(), u.ID, "create", "service", id, clientIP(r))
|
|
writeJSON(w, http.StatusCreated, envelope{Data: map[string]any{"id": id}})
|
|
}
|