1.4 KiB
1.4 KiB
Architect — F-020 Shipping module
Feature
F-020 adds server-side shipping quotation behind ShippingService.calculate(cart, address).
Design
Module boundaries
Create project/src/modules/shipping/ with domain/application/infrastructure/api/tests. Shipping owns zones and methods; it does not own cart data. Callers pass a cart summary and destination address into the public service.
Data model
Add migration 015_shipping.js:
shipping_zones: id, name, country, postal_code_prefix nullable, active.shipping_methods: id, zone_id, name, base_cost_cents, free_shipping_threshold_cents nullable, active.
Rules
- Address matching uses country plus optional postal-code prefix. Prefer the most specific prefix.
ShippingService.calculate(cart, address)returns the cheapest active method in the matching zone.- If cart total is at or above method threshold, shipping cost is zero.
- If no zone/method matches, throw a domain error mapped to HTTP 422.
- Carrier adapter is an interface only; no real carrier API.
API
- Admin create/update can be minimal for test setup:
POST /shipping/zones,POST /shipping/methods. - Public/authenticated calculation endpoint:
POST /shipping/calculatewith cart total/address payload.
Acceptance trace
- Known zone returns shipping cost.
- Unknown zone returns HTTP 422 with clear code.
- Cart above free shipping threshold returns zero cost.