4.6 KiB
4.6 KiB
1. Migration and shared contract
- 1.1 Add migration
0017_freight_templates.sql:freight_templates(shop FK, name, default flag with a partial unique index per shop, always-free toggle,by_piece/by_weightpricing method, first/additional unit fees as i64 minor units, integer first/additional unit sizes in pieces or grams, optional free-shipping threshold in i64 minor units),freight_region_rules(template FK, region code set, overriding fees and unit sizes),shipping_companies(code,{en, zh}JSONB name),orders.shipping_fee_minor,order_itemspricing-method and template-id snapshot columns, andshipments.shipping_company_code, with shop/template indexes and cascading deletes. - 1.2 Add shared freight template, region rule, shipping company, and checkout shipping-quote types plus
@vmall/sharedAPI methods for merchant template CRUD, region-rule editing, company listing, and checkout fee quoting; all money in i64 minor units and weights in integer grams, no floats. - 1.3 Implement
apps/api/src/modules/freight/repository, service, DTO, handlers, and module registration with shop routes scoped throughown_shopand services returningApiResult<Dto>; add a product-to-template link on the product edit contract, rejecting templates of another shop.
2. Calculation service and tests
- 2.1 Implement the pure shipping calculation service: per-shop grouping by resolved template (product template first, shop default second, zero fee fallback), quantity or integer-weight merging within a group, first-unit fee plus per-additional-unit fees with part units rounding up, always-free and free-shipping-threshold checks before fees, and region-rule fee overrides for matching destinations.
- 2.2 Wire checkout to the calculation service in the order-creation transaction: require the destination address, compute each shop order's fee server-side ignoring client amounts, add it to the order total, and persist
shipping_fee_minorplus per-item pricing-method and template snapshots. - 2.3 Add focused calculation tests at the boundaries: free-shipping threshold met and unmet, region rule overriding default fees, mixed templates in one shop order, partial additional-unit rounding, by-weight versus by-piece merging, and the no-template zero-fee fallback.
3. Shop-admin pages
- 3.1 Build the shop-admin freight template management page (list, create/edit, default toggle, always-free and threshold fields, pricing method and unit sizes, region-rule editor, delete) reading and writing through
@vmall/shared, styled with@vmall/uiprimitives and shared tokens, with a navigation entry beside existing shop operations. - 3.2 Extend the shop-admin fulfillment flow with a shipping-company selector populated from the shared dictionary, required before marking an order shipped, showing the recorded company afterwards.
4. Mall checkout and mock
- 4.1 Implement the shared shipping-quote and company client methods in
apps/mall/mock/api.tswith deterministic fixture templates (per-shop by-piece and by-weight cases plus one region override), and register the shipping surface in Mall API selection with exact shared-client method picks, enabling it in the default live configuration alongsideLIVE_PICKS. - 4.2 Update Mall checkout to select the shipping address before quoting, render each shop group's server-computed delivery fee and the combined shipping total in the selected currency, and show the persisted
shipping_feeon payment and order detail. - 4.3 Add bilingual en/zh checkout shipping strings through the existing Mall locale source without per-page hard-coded copy.
5. Verification and tracker cleanup
- 5.1 Add isolated API integration tests in
apps/api/tests/, reusing thetests/common/mod.rsfixtures, covering freight template CRUD withown_shopisolation and single-default enforcement, checkout fee persistence and totals for multi-shop carts, region-rule and free-shipping-threshold edges, snapshot stability after template edits, and shipping-company selection and rejection of unknown companies. - 5.2 Build the affected frontends because the shared contract changes:
pnpm --filter @vmall/shop-admin build,pnpm --filter @vmall/mall build, andpnpm --filter @vmall/admin build. - 5.3 Browser-smoke the running stack: create a template with a region rule in shop-admin, run a two-shop Mall checkout showing per-shop fees and totals, change the address to see fees update, pay, and ship with a selected company.
- 5.4 Run
openspec change validate add-freight-templates --strictandopenspec validate --all --strict, and check every OpenSpec task.