Files
vmall/openspec/changes/add-freight-templates/proposal.md
T

3.4 KiB

Why

Checkout currently sums item prices only, so orders carry no delivery cost and their totals are not what a buyer would really pay. Merchants have no way to charge different shipping for distant regions, heavier parcels, or small orders, and fulfillment cannot record which carrier moved a parcel. Adding freight templates and server-side shipping calculation makes order money truthful end to end.

What Changes

  • Add merchant-scoped freight templates: name, default-template flag, always-free toggle, pricing method by_piece or by_weight, first-unit and additional-unit fees in i64 minor units, integer first/additional unit sizes (pieces or grams), and an optional free-shipping threshold in i64 minor units.
  • Add per-template region rules that override the template's default fees for a set of destination regions, using a simplified region code table / text matching explicitly scoped in the spec (not a full national region tree).
  • Associate each product with a freight template, resolving fees product template first and falling back to the shop's default template.
  • Calculate shipping on the server at checkout: group the shop's items by resolved template, merge quantities or integer weights per template group, apply always-free and threshold free shipping first, let matching region rules override the default first/additional fees, and write each shop order's fee into the order total. Client-supplied amounts are never trusted.
  • Snapshot the pricing method used on order items and persist each order's shipping_fee_minor.
  • Add a platform shipping-company dictionary and let merchants pick the company when shipping an order.
  • Surface fees in the merchant console (freight template management, company selection) and in Mall checkout (per-shop delivery fee and total), behind the @vmall/shared contract with a fixed-adapter fallback.

Capabilities

New Capabilities

  • shipping: Merchant freight templates with region rules and free-shipping policy, default-template resolution, server-side per-shop shipping fee calculation, and a shipping-company dictionary with merchant selection at fulfillment.

Modified Capabilities

  • order: Checkout computes per-shop shipping fees from the shipping capability and persists shipping-fee and item pricing-method snapshots on the order.
  • frontend-shop-admin: Shop users manage freight templates and region rules and choose a shipping company when shipping an order.
  • frontend-mall: Checkout shows each shop order's delivery fee and the combined shipping total.

Non-goals

A full national region tree and region database (a simplified region code table / text matching is used and its scope is documented in the spec), multi-warehouse dispatch, carrier tracking APIs, electronic waybills, volumetric weight, per-SKU shipping overrides beyond the product template link, and cross-shop free-shipping thresholds are excluded.

Impact

Adds one Postgres migration (freight templates, region rules, shipping companies, and order/order-item columns), a Rust freight module with a pure calculation service wired into checkout, shared types and API methods in @vmall/shared, a Mall mock-adapter implementation and live-domain pick for the new shipping surface, shop-admin freight-template and fulfillment pages, and Mall checkout fee display. All money stays in i64 minor units and weights in integer grams; no floating-point amounts are introduced.