61 lines
2.7 KiB
Go
61 lines
2.7 KiB
Go
// Package order is the platform's shared order seam: the exported wire shape of
|
|
// the `order.created` domain event (B4.1). It is the contract between the order
|
|
// service (producer) and every reactor — inventory commit, fulfillment
|
|
// allocation, loyalty, ERP sync — none of which the order service knows about.
|
|
//
|
|
// Like platform/catalog and platform/inventory, it holds only the wire value
|
|
// types + encode/decode, and imports only the stdlib.
|
|
//
|
|
// `order.created` is a FACT, not a request: by the time it is emitted the order
|
|
// is placed and paid. Reactors must be idempotent (the transport is
|
|
// at-least-once) and must not assume they can refuse it — the sale already
|
|
// happened. Oversell on commit is reconciled downstream (backorder), not
|
|
// prevented here.
|
|
package order
|
|
|
|
import "encoding/json"
|
|
|
|
// Line is one ordered line item, reduced to what reactors need: the SKU, how
|
|
// many units sold, the inventory location to commit against, and whether the
|
|
// item is drop-ship (fulfilled by the supplier, never decremented from local
|
|
// stock). Pricing/tax live in the order grain, not on this seam.
|
|
type Line struct {
|
|
SKU string `json:"sku"`
|
|
Quantity int `json:"quantity"`
|
|
// Location is the inventory location / store id to decrement. Empty means
|
|
// "use the order's Country" (central stock) — see Created.Country.
|
|
Location string `json:"location,omitempty"`
|
|
// DropShip marks items fulfilled directly by the supplier. The inventory
|
|
// reactor must skip the stock decrement for these lines.
|
|
DropShip bool `json:"drop_ship,omitempty"`
|
|
}
|
|
|
|
// Created is the payload of an event.OrderCreated envelope.
|
|
//
|
|
// Country is the default inventory location for the commit (central stock). A
|
|
// Line may override it with its own Location (store id); when a line's Location
|
|
// is empty the commit falls back to Country. See docs/inventory-shape.md.
|
|
type Created struct {
|
|
OrderID string `json:"order_id"`
|
|
OrderReference string `json:"order_reference,omitempty"`
|
|
CartID string `json:"cart_id,omitempty"`
|
|
Country string `json:"country"`
|
|
Currency string `json:"currency,omitempty"`
|
|
CustomerEmail string `json:"customer_email,omitempty"`
|
|
// CustomerID is the customer profile ID for identity linking (B0.4). Reactors
|
|
// (e.g. profile service) use this to link the order to the customer profile.
|
|
CustomerID string `json:"customer_id,omitempty"`
|
|
Lines []Line `json:"lines"`
|
|
PlacedAtMs int64 `json:"placed_at_ms,omitempty"`
|
|
}
|
|
|
|
// Encode serialises the payload for event.Event.Payload.
|
|
func (c Created) Encode() ([]byte, error) { return json.Marshal(c) }
|
|
|
|
// Decode parses an order.created payload — the consumer side of Encode.
|
|
func Decode(raw []byte) (Created, error) {
|
|
var c Created
|
|
err := json.Unmarshal(raw, &c)
|
|
return c, err
|
|
}
|