feat(mall): address book wave 7 frontend, contract, and archive

Live addresses domain for the mall: shared contract (AddressBookEntry +
five client methods), mock adapter state v3, live domain pick, addresses
page CRUD, checkout saved-address picker with manual fallback, demo seed,
and the archived change plus address-book capability spec.
This commit is contained in:
Chengdong Zhang
2026-09-18 16:00:05 +08:00
parent 5e866d08f4
commit c51e96ae41
17 changed files with 467 additions and 88 deletions
@@ -0,0 +1,29 @@
# Tasks: replace-mock-api-wave-7
## 1. Backend
- [x] `apps/api/migrations/0009_addresses.sql`: table + `addresses_one_default` partial unique index
- [x] `apps/api/src/routes/addresses.rs`: list/create/update/delete/set-default; customer role; `WHERE user_id` ownership (404 cross-user); transactional default switching; first address auto-default; delete-default promotes latest remaining
- [x] Register module + router; `AddressBookEntry` row model
## 2. Shared contract
- [x] `packages/shared/src/types.ts`: `AddressBookEntry`
- [x] `packages/shared/src/api.ts`: `listMyAddresses`, `createAddress`, `updateAddress`, `deleteAddress`, `setDefaultAddress`
## 3. Mock adapter
- [x] `apps/mall/mock/api.ts`: same five methods over persisted mock state (seed from `MOCK_ADDRESSES`)
- [x] `apps/mall/plugins/api.ts`: `addresses` live pick + `DEFAULT_LIVE_DOMAINS` entry
## 4. Mall pages
- [x] `user/addresses.vue`: real CRUD via `$api` (modal add/edit, delete, set-default)
- [x] `checkout/index.vue`: load addresses from `$api`; radio select; inline manual form fallback when empty; submit selected address
- [x] Locale keys (user/checkout domains, en+zh)
## 5. Seed + tests
- [x] `scripts/seed-demo.mjs`: two idempotent demo customer addresses
- [x] `apps/api/tests/addresses.rs`: CRUD, cross-user 404, single-default invariant, delete-default promotion, non-customer 403
## 6. Verify
- [x] `cargo test -p vmall-api` green (docker vmall_test + Redis)
- [x] `pnpm --filter @vmall/mall build` + shop-admin + admin builds green (contract change)
- [x] `openspec validate replace-mock-api-wave-7 --strict` green
- [x] Browser smoke: address CRUD in user center; checkout with saved address end-to-end