Shipping is deceptively simple until a retailer hands you the real rules: flat rates for metro, tiered rates by state, composite bundles where one SKU ships from the warehouse and another drops from the supplier, and the inevitable 'but also, on weekends…' clause.
Rules as data
I've stopped modelling shipping as logic. Every rule is a typed row: a predicate (where does it apply?), a priority (what beats what?), and a resolver (how do we price it?). Zod validates rows at read time; tests drive examples; the admin UI renders rows as editable cards. When the team edits a rule, they're editing a row, not changing code.
Composite products
When a cart contains a composite SKU, split the cart into shipping buckets before applying rules. Each bucket gets its own rate quote; the merged result is what the customer sees. Don't try to be clever with a single pass — it's two passes that stay comprehensible in six months.
The shipping engine should be something the ops team can read, not a thing only engineering can fear.
