60 lines
2.2 KiB
Go
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)
|
|
}
|