feat: add carpet

This commit is contained in:
2026-07-03 21:58:28 +03:30
parent d290ba86bb
commit 413fca68cc
20 changed files with 421 additions and 16 deletions
+67
View File
@@ -87,6 +87,73 @@ func (h *Handler) BuyCard(w http.ResponseWriter, r *http.Request) {
}
}
// Carpets — GET /api/carpets (فرش‌ها + مالکیت + فرشِ انتخابی)
func (h *Handler) Carpets(w http.ResponseWriter, r *http.Request) {
id, ok := uid(r)
if !ok {
httpx.Error(w, http.StatusUnauthorized, "unauthorized")
return
}
carpets, err := h.svc.Carpets(r.Context(), id)
if err != nil {
httpx.Error(w, http.StatusInternalServerError, "server error")
return
}
selected := "classic"
if p, _ := h.svc.GetProfile(r.Context(), id); p != nil && p.SelectedCarpet != "" {
selected = p.SelectedCarpet
}
httpx.JSON(w, http.StatusOK, map[string]any{
"carpets": carpets,
"selected": selected,
})
}
// BuyCarpet — POST /api/shop/buy-carpet
func (h *Handler) BuyCarpet(w http.ResponseWriter, r *http.Request) {
h.carpetAction(w, r, false)
}
// SelectCarpet — POST /api/shop/select-carpet
func (h *Handler) SelectCarpet(w http.ResponseWriter, r *http.Request) {
h.carpetAction(w, r, true)
}
func (h *Handler) carpetAction(w http.ResponseWriter, r *http.Request, sel bool) {
id, ok := uid(r)
if !ok {
httpx.Error(w, http.StatusUnauthorized, "unauthorized")
return
}
var req struct {
CarpetID string `json:"carpet_id"`
}
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
httpx.Error(w, http.StatusBadRequest, "invalid body")
return
}
var err error
if sel {
err = h.svc.SelectCarpet(r.Context(), id, req.CarpetID)
} else {
err = h.svc.BuyCarpet(r.Context(), id, req.CarpetID)
}
switch {
case err == nil:
httpx.JSON(w, http.StatusOK, map[string]string{"message": "ok"})
case errors.Is(err, ErrNotFound):
httpx.Error(w, http.StatusNotFound, "carpet not found")
case errors.Is(err, ErrAlreadyOwned):
httpx.Error(w, http.StatusConflict, "already owned")
case errors.Is(err, ErrNotOwned):
httpx.Error(w, http.StatusForbidden, "carpet not owned")
case errors.Is(err, ErrInsufficient):
httpx.Error(w, http.StatusPaymentRequired, "insufficient coins")
default:
httpx.Error(w, http.StatusInternalServerError, "server error")
}
}
// ChatPacks — GET /api/chat-packs (بسته‌های پیام/شکلک + مالکیتِ کاربر)
func (h *Handler) ChatPacks(w http.ResponseWriter, r *http.Request) {
id, ok := uid(r)