missing updates #5

Merged
mats merged 77 commits from refactor/http-proxy into main 2025-10-14 23:12:06 +02:00
5 changed files with 781 additions and 28 deletions
Showing only changes of commit 11e82de114 - Show all commits

5
cmd/backoffice/main.go Normal file
View File

@@ -0,0 +1,5 @@
package main
func main() {
// Your code here
}

View File

@@ -396,6 +396,8 @@ func main() {
w.Write([]byte("1.0.0"))
})
mux.HandleFunc("/openapi.json", ServeEmbeddedOpenAPI)
sigs := make(chan os.Signal, 1)
done := make(chan bool, 1)
signal.Notify(sigs, syscall.SIGTERM)

677
cmd/cart/openapi.json Normal file
View File

@@ -0,0 +1,677 @@
{
"openapi": "3.0.3",
"info": {
"title": "Cart Service API",
"description": "HTTP API for shopping cart operations (cookie-based or explicit id): retrieve cart, add/replace items, update quantity, manage deliveries.",
"version": "1.0.0"
},
"servers": [
{
"url": "https://cart.tornberg.me",
"description": "Production server"
},
{
"url": "http://localhost:8080",
"description": "Local development (cart API mounted under /cart)"
}
],
"paths": {
"/cart/": {
"get": {
"summary": "Get (or create) current cart (cookie based)",
"description": "Returns the current cart. If no cartid cookie is present a new cart is created and Set-Cart-Id response header plus a Set-Cookie header are sent.",
"responses": {
"200": {
"description": "Cart retrieved",
"headers": {
"Set-Cart-Id": {
"description": "Returned when a new cart was created this request",
"schema": { "type": "string" }
},
"X-Pod-Name": {
"description": "Pod identifier serving the request",
"schema": { "type": "string" }
}
},
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/CartGrain" }
}
}
},
"500": { "description": "Server error" }
}
},
"post": {
"summary": "Add single SKU (body)",
"description": "Adds (or increases quantity of) a single SKU using request body.",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/AddRequest" }
}
}
},
"responses": {
"200": {
"description": "Item added",
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/CartGrain" }
}
}
},
"400": { "description": "Invalid request body" },
"500": { "description": "Server error" }
}
},
"put": {
"summary": "Change quantity of an item",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/ChangeQuantity" }
}
}
},
"responses": {
"200": {
"description": "Quantity updated",
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/CartGrain" }
}
}
},
"400": { "description": "Invalid request body" },
"500": { "description": "Server error" }
}
},
"delete": {
"summary": "Clear cart cookie (logical cart reused only if referenced later)",
"description": "Removes the cartid cookie by expiring it. Does not mutate server-side cart state.",
"responses": {
"200": { "description": "Cookie cleared (empty body)" }
}
}
},
"/cart/add/{sku}": {
"get": {
"summary": "Add a SKU (path)",
"description": "Adds a single SKU with implicit quantity 1. Country inferred from Host header (-se / -no).",
"parameters": [{ "$ref": "#/components/parameters/SkuParam" }],
"responses": {
"200": {
"description": "Item added",
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/CartGrain" }
}
}
},
"500": { "description": "Server error" }
}
}
},
"/cart/add": {
"post": {
"summary": "Add multiple items (append)",
"description": "Adds multiple items to the cart without clearing existing contents.",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/SetCartItems" }
}
}
},
"responses": {
"200": {
"description": "Items added",
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/CartGrain" }
}
}
},
"400": { "description": "Invalid body" },
"500": { "description": "Server error" }
}
}
},
"/cart/set": {
"post": {
"summary": "Replace cart contents",
"description": "Clears the cart first, then adds the provided items (idempotent with respect to target set).",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/SetCartItems" }
}
}
},
"responses": {
"200": {
"description": "Cart replaced",
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/CartGrain" }
}
}
},
"400": { "description": "Invalid body" },
"500": { "description": "Server error" }
}
}
},
"/cart/{itemId}": {
"delete": {
"summary": "Remove item by line id",
"parameters": [
{
"name": "itemId",
"in": "path",
"required": true,
"schema": { "type": "integer", "format": "int64", "minimum": 0 },
"description": "Internal cart line item identifier (not SKU)."
}
],
"responses": {
"200": {
"description": "Item removed",
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/CartGrain" }
}
}
},
"400": { "description": "Bad id" },
"500": { "description": "Server error" }
}
}
},
"/cart/delivery": {
"post": {
"summary": "Set (add) delivery",
"description": "Adds a delivery option referencing one or more line item ids.",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/SetDeliveryRequest" }
}
}
},
"responses": {
"200": {
"description": "Delivery added/updated",
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/CartGrain" }
}
}
},
"400": { "description": "Invalid body" },
"500": { "description": "Server error" }
}
}
},
"/cart/delivery/{deliveryId}": {
"delete": {
"summary": "Remove delivery",
"parameters": [{ "$ref": "#/components/parameters/DeliveryIdParam" }],
"responses": {
"200": {
"description": "Delivery removed",
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/CartGrain" }
}
}
},
"400": { "description": "Bad id" },
"500": { "description": "Server error" }
}
}
},
"/cart/delivery/{deliveryId}/pickupPoint": {
"put": {
"summary": "Set pickup point for delivery",
"parameters": [{ "$ref": "#/components/parameters/DeliveryIdParam" }],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/PickupPoint" }
}
}
},
"responses": {
"200": {
"description": "Pickup point set",
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/CartGrain" }
}
}
},
"400": { "description": "Invalid body" },
"500": { "description": "Server error" }
}
}
},
"/cart/byid/{id}": {
"get": {
"summary": "Get cart by explicit id",
"parameters": [{ "$ref": "#/components/parameters/CartIdParam" }],
"responses": {
"200": {
"description": "Cart retrieved",
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/CartGrain" }
}
}
},
"400": { "description": "Invalid id" },
"500": { "description": "Server error" }
}
},
"post": {
"summary": "Add single SKU (body) by cart id",
"parameters": [{ "$ref": "#/components/parameters/CartIdParam" }],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/AddRequest" }
}
}
},
"responses": {
"200": {
"description": "Item added",
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/CartGrain" }
}
}
},
"400": { "description": "Invalid body" },
"500": { "description": "Server error" }
}
},
"put": {
"summary": "Change quantity (by id variant)",
"parameters": [{ "$ref": "#/components/parameters/CartIdParam" }],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/ChangeQuantity" }
}
}
},
"responses": {
"200": {
"description": "Quantity updated",
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/CartGrain" }
}
}
},
"400": { "description": "Invalid body" },
"500": { "description": "Server error" }
}
}
},
"/cart/byid/{id}/add/{sku}": {
"get": {
"summary": "Add SKU (path) by explicit cart id",
"parameters": [
{ "$ref": "#/components/parameters/CartIdParam" },
{ "$ref": "#/components/parameters/SkuParam" }
],
"responses": {
"200": {
"description": "Item added",
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/CartGrain" }
}
}
},
"400": { "description": "Invalid id/sku" },
"500": { "description": "Server error" }
}
}
},
"/cart/byid/{id}/{itemId}": {
"delete": {
"summary": "Remove item (by id variant)",
"parameters": [
{ "$ref": "#/components/parameters/CartIdParam" },
{
"name": "itemId",
"in": "path",
"required": true,
"schema": { "type": "integer", "format": "int64", "minimum": 0 }
}
],
"responses": {
"200": {
"description": "Item removed",
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/CartGrain" }
}
}
},
"400": { "description": "Invalid id" },
"500": { "description": "Server error" }
}
}
},
"/cart/byid/{id}/delivery": {
"post": {
"summary": "Set delivery (by id variant)",
"parameters": [{ "$ref": "#/components/parameters/CartIdParam" }],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/SetDeliveryRequest" }
}
}
},
"responses": {
"200": {
"description": "Delivery added/updated",
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/CartGrain" }
}
}
},
"400": { "description": "Invalid body" },
"500": { "description": "Server error" }
}
}
},
"/cart/byid/{id}/delivery/{deliveryId}": {
"delete": {
"summary": "Remove delivery (by id variant)",
"parameters": [
{ "$ref": "#/components/parameters/CartIdParam" },
{ "$ref": "#/components/parameters/DeliveryIdParam" }
],
"responses": {
"200": {
"description": "Delivery removed",
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/CartGrain" }
}
}
},
"400": { "description": "Invalid ids" },
"500": { "description": "Server error" }
}
}
},
"/cart/byid/{id}/delivery/{deliveryId}/pickupPoint": {
"put": {
"summary": "Set pickup point (by id variant)",
"parameters": [
{ "$ref": "#/components/parameters/CartIdParam" },
{ "$ref": "#/components/parameters/DeliveryIdParam" }
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/PickupPoint" }
}
}
},
"responses": {
"200": {
"description": "Pickup point updated",
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/CartGrain" }
}
}
},
"400": { "description": "Invalid body" },
"500": { "description": "Server error" }
}
}
},
"/healthz": {
"get": {
"summary": "Liveness & capacity probe",
"responses": {
"200": { "description": "Healthy" },
"500": { "description": "Unhealthy" }
}
}
},
"/readyz": {
"get": {
"summary": "Readiness probe",
"responses": {
"200": { "description": "Ready" }
}
}
},
"/livez": {
"get": {
"summary": "Liveness probe",
"responses": {
"200": { "description": "Alive" }
}
}
},
"/version": {
"get": {
"summary": "Service version",
"responses": {
"200": {
"description": "Version string",
"content": {
"text/plain": {
"schema": { "type": "string", "example": "1.0.0" }
}
}
}
}
}
}
},
"components": {
"parameters": {
"SkuParam": {
"name": "sku",
"in": "path",
"required": true,
"schema": { "type": "string" }
},
"CartIdParam": {
"name": "id",
"in": "path",
"required": true,
"description": "Base62 encoded cart id",
"schema": {
"type": "string",
"pattern": "^[0-9A-Za-z]+$",
"minLength": 1
}
},
"DeliveryIdParam": {
"name": "deliveryId",
"in": "path",
"required": true,
"schema": { "type": "integer", "format": "int64", "minimum": 0 }
}
},
"schemas": {
"CartGrain": {
"type": "object",
"description": "Cart aggregate (actor state)",
"properties": {
"id": {
"type": "string",
"description": "Cart id (base62 encoded uint64)"
},
"items": {
"type": "array",
"items": { "$ref": "#/components/schemas/CartItem" }
},
"totalPrice": { "type": "integer", "format": "int64" },
"totalTax": { "type": "integer", "format": "int64" },
"totalDiscount": { "type": "integer", "format": "int64" },
"deliveries": {
"type": "array",
"items": { "$ref": "#/components/schemas/CartDelivery" }
},
"processing": { "type": "boolean" },
"paymentInProgress": { "type": "boolean" },
"orderReference": { "type": "string" },
"paymentStatus": { "type": "string" }
},
"required": ["id", "items", "totalPrice", "totalTax", "totalDiscount"]
},
"CartItem": {
"type": "object",
"properties": {
"id": { "type": "integer" },
"itemId": { "type": "integer" },
"parentId": { "type": "integer" },
"sku": { "type": "string" },
"name": { "type": "string" },
"price": { "type": "integer", "format": "int64" },
"totalPrice": { "type": "integer", "format": "int64" },
"totalTax": { "type": "integer", "format": "int64" },
"orgPrice": { "type": "integer", "format": "int64" },
"stock": {
"type": "integer",
"description": "0=OutOfStock,1=LowStock,2=InStock"
},
"qty": { "type": "integer" },
"tax": { "type": "integer" },
"taxRate": { "type": "integer" },
"brand": { "type": "string" },
"category": { "type": "string" },
"category2": { "type": "string" },
"category3": { "type": "string" },
"category4": { "type": "string" },
"category5": { "type": "string" },
"disclaimer": { "type": "string" },
"sellerId": { "type": "string" },
"sellerName": { "type": "string" },
"type": { "type": "string", "description": "Article type" },
"image": { "type": "string" },
"outlet": { "type": "string", "nullable": true },
"storeId": { "type": "string", "nullable": true }
},
"required": ["id", "sku", "name", "price", "qty", "tax"]
},
"CartDelivery": {
"type": "object",
"properties": {
"id": { "type": "integer" },
"provider": { "type": "string" },
"price": { "type": "integer", "format": "int64" },
"items": {
"type": "array",
"items": { "type": "integer" }
},
"pickupPoint": { "$ref": "#/components/schemas/PickupPoint" }
},
"required": ["id", "provider", "price", "items"]
},
"PickupPoint": {
"type": "object",
"properties": {
"id": { "type": "string" },
"name": { "type": "string", "nullable": true },
"address": { "type": "string", "nullable": true },
"city": { "type": "string", "nullable": true },
"zip": { "type": "string", "nullable": true },
"country": { "type": "string", "nullable": true }
},
"required": ["id"]
},
"AddRequest": {
"type": "object",
"properties": {
"quantity": {
"type": "integer",
"format": "int32",
"minimum": 1,
"default": 1
},
"sku": { "type": "string" },
"country": {
"type": "string",
"description": "Two-letter country code (inferred if omitted)"
},
"storeId": { "type": "string", "nullable": true }
},
"required": ["sku"]
},
"ChangeQuantity": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"format": "int64",
"description": "Cart line item id"
},
"quantity": { "type": "integer", "format": "int32", "minimum": 0 }
},
"required": ["id", "quantity"]
},
"Item": {
"type": "object",
"properties": {
"sku": { "type": "string" },
"quantity": { "type": "integer", "minimum": 1 },
"storeId": { "type": "string", "nullable": true }
},
"required": ["sku", "quantity"]
},
"SetCartItems": {
"type": "object",
"properties": {
"country": { "type": "string" },
"items": {
"type": "array",
"items": { "$ref": "#/components/schemas/Item" },
"minItems": 0
}
},
"required": ["items"]
},
"SetDeliveryRequest": {
"type": "object",
"properties": {
"provider": { "type": "string" },
"items": {
"type": "array",
"items": { "type": "integer", "format": "int64" },
"description": "Line item ids served by this delivery"
},
"pickupPoint": { "$ref": "#/components/schemas/PickupPoint" }
},
"required": ["provider", "items"]
}
}
},
"tags": [{ "name": "Cart" }, { "name": "Delivery" }, { "name": "System" }]
}

69
cmd/cart/openapi_embed.go Normal file
View File

@@ -0,0 +1,69 @@
package main
import (
"bytes"
"crypto/sha256"
_ "embed"
"encoding/hex"
"net/http"
"sync"
)
// openapi_embed.go: Provides embedded OpenAPI spec and helper to mount handler.
//go:embed openapi.json
var openapiJSON []byte
var (
openapiOnce sync.Once
openapiETag string
)
// initOpenAPIMetadata computes immutable metadata for the embedded spec.
func initOpenAPIMetadata() {
sum := sha256.Sum256(openapiJSON)
openapiETag = `W/"` + hex.EncodeToString(sum[:8]) + `"` // weak ETag with first 8 bytes
}
// ServeEmbeddedOpenAPI serves the embedded OpenAPI JSON spec at /openapi.json.
// It supports GET and HEAD and implements basic ETag caching.
func ServeEmbeddedOpenAPI(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodGet && r.Method != http.MethodHead {
w.Header().Set("Allow", "GET, HEAD")
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
return
}
openapiOnce.Do(initOpenAPIMetadata)
w.Header().Set("Content-Type", "application/json; charset=utf-8")
w.Header().Set("Cache-Control", "no-cache")
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("ETag", openapiETag)
if match := r.Header.Get("If-None-Match"); match != "" {
if bytes.Contains([]byte(match), []byte(openapiETag)) {
w.WriteHeader(http.StatusNotModified)
return
}
}
if r.Method == http.MethodHead {
w.WriteHeader(http.StatusOK)
return
}
w.WriteHeader(http.StatusOK)
_, _ = w.Write(openapiJSON)
}
// Optional: function to access raw spec bytes programmatically.
func OpenAPISpecBytes() []byte {
return openapiJSON
}
// Optional: function to access current ETag.
func OpenAPIETag() string {
openapiOnce.Do(initOpenAPIMetadata)
return openapiETag
}

View File

@@ -33,7 +33,7 @@ func (s *PoolServer) ApplyLocal(id CartId, mutation ...proto.Message) (*CartGrai
return s.Apply(uint64(id), mutation...)
}
func (s *PoolServer) HandleGet(w http.ResponseWriter, r *http.Request, id CartId) error {
func (s *PoolServer) GetCartHandler(w http.ResponseWriter, r *http.Request, id CartId) error {
grain, err := s.Get(uint64(id))
if err != nil {
return err
@@ -42,7 +42,7 @@ func (s *PoolServer) HandleGet(w http.ResponseWriter, r *http.Request, id CartId
return s.WriteResult(w, grain)
}
func (s *PoolServer) HandleAddSku(w http.ResponseWriter, r *http.Request, id CartId) error {
func (s *PoolServer) AddSkuToCartHandler(w http.ResponseWriter, r *http.Request, id CartId) error {
sku := r.PathValue("sku")
msg, err := GetItemAddMessage(sku, 1, getCountryFromHost(r.Host), nil)
if err != nil {
@@ -72,7 +72,7 @@ func (s *PoolServer) WriteResult(w http.ResponseWriter, result *CartGrain) error
return err
}
func (s *PoolServer) HandleDeleteItem(w http.ResponseWriter, r *http.Request, id CartId) error {
func (s *PoolServer) DeleteItemHandler(w http.ResponseWriter, r *http.Request, id CartId) error {
itemIdString := r.PathValue("itemId")
itemId, err := strconv.Atoi(itemIdString)
@@ -92,7 +92,7 @@ type SetDeliveryRequest struct {
PickupPoint *messages.PickupPoint `json:"pickupPoint,omitempty"`
}
func (s *PoolServer) HandleSetDelivery(w http.ResponseWriter, r *http.Request, id CartId) error {
func (s *PoolServer) SetDeliveryHandler(w http.ResponseWriter, r *http.Request, id CartId) error {
delivery := SetDeliveryRequest{}
err := json.NewDecoder(r.Body).Decode(&delivery)
@@ -110,7 +110,7 @@ func (s *PoolServer) HandleSetDelivery(w http.ResponseWriter, r *http.Request, i
return s.WriteResult(w, data)
}
func (s *PoolServer) HandleSetPickupPoint(w http.ResponseWriter, r *http.Request, id CartId) error {
func (s *PoolServer) SetPickupPointHandler(w http.ResponseWriter, r *http.Request, id CartId) error {
deliveryIdString := r.PathValue("deliveryId")
deliveryId, err := strconv.Atoi(deliveryIdString)
@@ -137,7 +137,7 @@ func (s *PoolServer) HandleSetPickupPoint(w http.ResponseWriter, r *http.Request
return s.WriteResult(w, reply)
}
func (s *PoolServer) HandleRemoveDelivery(w http.ResponseWriter, r *http.Request, id CartId) error {
func (s *PoolServer) RemoveDeliveryHandler(w http.ResponseWriter, r *http.Request, id CartId) error {
deliveryIdString := r.PathValue("deliveryId")
deliveryId, err := strconv.Atoi(deliveryIdString)
@@ -151,7 +151,7 @@ func (s *PoolServer) HandleRemoveDelivery(w http.ResponseWriter, r *http.Request
return s.WriteResult(w, reply)
}
func (s *PoolServer) HandleQuantityChange(w http.ResponseWriter, r *http.Request, id CartId) error {
func (s *PoolServer) QuantityChangeHandler(w http.ResponseWriter, r *http.Request, id CartId) error {
changeQuantity := messages.ChangeQuantity{}
err := json.NewDecoder(r.Body).Decode(&changeQuantity)
if err != nil {
@@ -196,7 +196,7 @@ func getMultipleAddMessages(items []Item, country string) []proto.Message {
return msgs
}
func (s *PoolServer) HandleSetCartItems(w http.ResponseWriter, r *http.Request, id CartId) error {
func (s *PoolServer) SetCartItemsHandler(w http.ResponseWriter, r *http.Request, id CartId) error {
setCartItems := SetCartItems{}
err := json.NewDecoder(r.Body).Decode(&setCartItems)
if err != nil {
@@ -214,7 +214,7 @@ func (s *PoolServer) HandleSetCartItems(w http.ResponseWriter, r *http.Request,
return s.WriteResult(w, reply)
}
func (s *PoolServer) HandleAddMultiple(w http.ResponseWriter, r *http.Request, id CartId) error {
func (s *PoolServer) AddMultipleItemHandler(w http.ResponseWriter, r *http.Request, id CartId) error {
setCartItems := SetCartItems{}
err := json.NewDecoder(r.Body).Decode(&setCartItems)
if err != nil {
@@ -228,7 +228,7 @@ func (s *PoolServer) HandleAddMultiple(w http.ResponseWriter, r *http.Request, i
return s.WriteResult(w, reply)
}
func (s *PoolServer) HandleAddRequest(w http.ResponseWriter, r *http.Request, id CartId) error {
func (s *PoolServer) AddSkuRequestHandler(w http.ResponseWriter, r *http.Request, id CartId) error {
addRequest := messages.AddRequest{}
err := json.NewDecoder(r.Body).Decode(&addRequest)
if err != nil {
@@ -447,28 +447,28 @@ func (s *PoolServer) Serve() *http.ServeMux {
w.WriteHeader(http.StatusOK)
})
mux.HandleFunc("GET /", CookieCartIdHandler(s.ProxyHandler(s.HandleGet)))
mux.HandleFunc("GET /add/{sku}", CookieCartIdHandler(s.ProxyHandler(s.HandleAddSku)))
mux.HandleFunc("POST /add", CookieCartIdHandler(s.ProxyHandler(s.HandleAddMultiple)))
mux.HandleFunc("POST /", CookieCartIdHandler(s.ProxyHandler(s.HandleAddRequest)))
mux.HandleFunc("POST /set", CookieCartIdHandler(s.ProxyHandler(s.HandleSetCartItems)))
mux.HandleFunc("DELETE /{itemId}", CookieCartIdHandler(s.ProxyHandler(s.HandleDeleteItem)))
mux.HandleFunc("PUT /", CookieCartIdHandler(s.ProxyHandler(s.HandleQuantityChange)))
mux.HandleFunc("GET /", CookieCartIdHandler(s.ProxyHandler(s.GetCartHandler)))
mux.HandleFunc("GET /add/{sku}", CookieCartIdHandler(s.ProxyHandler(s.AddSkuToCartHandler)))
mux.HandleFunc("POST /add", CookieCartIdHandler(s.ProxyHandler(s.AddMultipleItemHandler)))
mux.HandleFunc("POST /", CookieCartIdHandler(s.ProxyHandler(s.AddSkuRequestHandler)))
mux.HandleFunc("POST /set", CookieCartIdHandler(s.ProxyHandler(s.SetCartItemsHandler)))
mux.HandleFunc("DELETE /{itemId}", CookieCartIdHandler(s.ProxyHandler(s.DeleteItemHandler)))
mux.HandleFunc("PUT /", CookieCartIdHandler(s.ProxyHandler(s.QuantityChangeHandler)))
mux.HandleFunc("DELETE /", CookieCartIdHandler(s.ProxyHandler(s.RemoveCartCookie)))
mux.HandleFunc("POST /delivery", CookieCartIdHandler(s.ProxyHandler(s.HandleSetDelivery)))
mux.HandleFunc("DELETE /delivery/{deliveryId}", CookieCartIdHandler(s.ProxyHandler(s.HandleRemoveDelivery)))
mux.HandleFunc("PUT /delivery/{deliveryId}/pickupPoint", CookieCartIdHandler(s.ProxyHandler(s.HandleSetPickupPoint)))
mux.HandleFunc("POST /delivery", CookieCartIdHandler(s.ProxyHandler(s.SetDeliveryHandler)))
mux.HandleFunc("DELETE /delivery/{deliveryId}", CookieCartIdHandler(s.ProxyHandler(s.RemoveDeliveryHandler)))
mux.HandleFunc("PUT /delivery/{deliveryId}/pickupPoint", CookieCartIdHandler(s.ProxyHandler(s.SetPickupPointHandler)))
//mux.HandleFunc("GET /checkout", CookieCartIdHandler(s.ProxyHandler(s.HandleCheckout)))
//mux.HandleFunc("GET /confirmation/{orderId}", CookieCartIdHandler(s.ProxyHandler(s.HandleConfirmation)))
mux.HandleFunc("GET /byid/{id}", CartIdHandler(s.ProxyHandler(s.HandleGet)))
mux.HandleFunc("GET /byid/{id}/add/{sku}", CartIdHandler(s.ProxyHandler(s.HandleAddSku)))
mux.HandleFunc("POST /byid/{id}", CartIdHandler(s.ProxyHandler(s.HandleAddRequest)))
mux.HandleFunc("DELETE /byid/{id}/{itemId}", CartIdHandler(s.ProxyHandler(s.HandleDeleteItem)))
mux.HandleFunc("PUT /byid/{id}", CartIdHandler(s.ProxyHandler(s.HandleQuantityChange)))
mux.HandleFunc("POST /byid/{id}/delivery", CartIdHandler(s.ProxyHandler(s.HandleSetDelivery)))
mux.HandleFunc("DELETE /byid/{id}/delivery/{deliveryId}", CartIdHandler(s.ProxyHandler(s.HandleRemoveDelivery)))
mux.HandleFunc("PUT /byid/{id}/delivery/{deliveryId}/pickupPoint", CartIdHandler(s.ProxyHandler(s.HandleSetPickupPoint)))
mux.HandleFunc("GET /byid/{id}", CartIdHandler(s.ProxyHandler(s.GetCartHandler)))
mux.HandleFunc("GET /byid/{id}/add/{sku}", CartIdHandler(s.ProxyHandler(s.AddSkuToCartHandler)))
mux.HandleFunc("POST /byid/{id}", CartIdHandler(s.ProxyHandler(s.AddSkuRequestHandler)))
mux.HandleFunc("DELETE /byid/{id}/{itemId}", CartIdHandler(s.ProxyHandler(s.DeleteItemHandler)))
mux.HandleFunc("PUT /byid/{id}", CartIdHandler(s.ProxyHandler(s.QuantityChangeHandler)))
mux.HandleFunc("POST /byid/{id}/delivery", CartIdHandler(s.ProxyHandler(s.SetDeliveryHandler)))
mux.HandleFunc("DELETE /byid/{id}/delivery/{deliveryId}", CartIdHandler(s.ProxyHandler(s.RemoveDeliveryHandler)))
mux.HandleFunc("PUT /byid/{id}/delivery/{deliveryId}/pickupPoint", CartIdHandler(s.ProxyHandler(s.SetPickupPointHandler)))
//mux.HandleFunc("GET /byid/{id}/checkout", CartIdHandler(s.ProxyHandler(s.HandleCheckout)))
//mux.HandleFunc("GET /byid/{id}/confirmation", CartIdHandler(s.ProxyHandler(s.HandleConfirmation)))