mirror of
https://github.com/marcusDenslow/terminalShop.git
synced 2026-10-26 02:08:46 +01:00
feat: implement server-side cart persistence with Stripe PaymentIntents Replaced the client-only in-mem cart with a database-backed cart system - Add Cart and CartItem GORM models (two-table design) - Add 6 cart API endpoints (get, set item, set address, set card, clear, conver) - Switch from Stripe Charge API to PaymentIntents with confirm:true - Add 9 API client methods for cart and card operations - Refactor TUI cart from map[int] (slice index) to map[uint] (CoffeeID) - Replace single-shot checkout with saveCardAndConvert multi-step flow - Add CheckingOut state with "submitting order..." processing indicator - Fix Stripe tokenization to use secret key for server-side SSH apps - Remove admin product CRUD endpoints and old checkout handler
61 lines
1.5 KiB
Go
61 lines
1.5 KiB
Go
package handlers
|
|
|
|
import (
|
|
"net/http"
|
|
"strconv"
|
|
|
|
"github.com/go-chi/chi/v5"
|
|
"terminalShop/pkg/database"
|
|
"terminalShop/pkg/models"
|
|
"terminalShop/pkg/utils"
|
|
)
|
|
|
|
// ProductHandler handles product-related requests
|
|
type ProductHandler struct{}
|
|
|
|
// NewProductHandler creates a new product handler
|
|
func NewProductHandler() *ProductHandler {
|
|
return &ProductHandler{}
|
|
}
|
|
|
|
// GetProducts returns all products from the database
|
|
func (h *ProductHandler) GetProducts(w http.ResponseWriter, r *http.Request) {
|
|
db := database.GetDB()
|
|
|
|
var products []models.Coffee
|
|
|
|
// Query all products from database
|
|
if err := db.Find(&products).Error; err != nil {
|
|
utils.RespondError(w, http.StatusInternalServerError, "DATABASE_ERROR", "failed to fetch products", nil)
|
|
return
|
|
}
|
|
|
|
utils.RespondSuccess(w, http.StatusOK, map[string]interface{}{
|
|
"products": products,
|
|
})
|
|
}
|
|
|
|
// GetProduct returns a single product by ID
|
|
func (h *ProductHandler) GetProduct(w http.ResponseWriter, r *http.Request) {
|
|
db := database.GetDB()
|
|
|
|
// Get ID from URL parameter
|
|
idStr := chi.URLParam(r, "id")
|
|
id, err := strconv.ParseUint(idStr, 10, 32)
|
|
if err != nil {
|
|
utils.RespondError(w, http.StatusBadRequest, "INVALID_ID", "invalid product ID", nil)
|
|
return
|
|
}
|
|
|
|
var product models.Coffee
|
|
if err := db.First(&product, id).Error; err != nil {
|
|
utils.RespondError(w, http.StatusNotFound, "NOT_FOUND", "product not found", nil)
|
|
return
|
|
}
|
|
|
|
utils.RespondSuccess(w, http.StatusOK, map[string]interface{}{
|
|
"product": product,
|
|
})
|
|
}
|
|
|