Files
platform/inventory/reservation.go
T
2026-06-29 12:35:32 +02:00

60 lines
2.2 KiB
Go

package inventory
import (
"context"
"time"
)
// Value types for inventory reservation — cross-module vocabulary shared by
// cart, checkout, backoffice, and the inventory service. Moving them here
// means consumers depend on platform/inventory rather than on the Redis
// implementation package (go-redis-inventory).
// SKU identifies a single stock-keeping unit.
type SKU string
// LocationID identifies a geographic stock location (e.g. "se", "no").
type LocationID string
// CartID identifies a shopping cart — used as the reservation holder key.
type CartID string
// InventoryReference identifies a specific SKU at a specific location.
type InventoryReference struct {
SKU SKU
LocationID LocationID
}
// CartReserveRequest is what a caller provides to reserve stock for a cart.
type CartReserveRequest struct {
*InventoryReference
CartID CartID
Quantity uint32
TTL time.Duration
}
// ReservationPolicy is the cross-module seam for inventory reservation.
// Cart mutations call Reserve on add-to-cart / change-quantity and Release on
// item removal. Checkout calls Available to validate stock before a payment
// session, and Release on cancel / destroy. Every implementation behind this
// interface is free to choose its internal storage (Redis Lua, in-memory map,
// actor grain, etc.) — the consumer never needs to know.
//
// This is the "policy-first seam" from docs/ARCHITECTURE.md:
// commerce policy lives here; the fast, contended storage lives behind it.
type ReservationPolicy interface {
// Reserve holds qty units of sku at locationID for the caller's cart.
// Returns an error if insufficient stock is available.
Reserve(ctx context.Context, req CartReserveRequest) error
// Release frees a prior reservation for the given cart at the given
// sku+location. Idempotent: releasing an already-released or expired
// reservation is a no-op.
Release(ctx context.Context, sku SKU, locationID LocationID, cartID CartID) error
// Available returns the quantity that can still be reserved right now —
// total stock minus all active reservations. Used by checkout to validate
// that the cart's items are still reservable before opening a payment session.
Available(ctx context.Context, sku SKU, locationID LocationID) (int64, error)
}