docs: confirm shopee field dictionary storage

This commit is contained in:
曾志威
2026-06-04 15:51:52 +08:00
parent f9b27102c8
commit 66c00d3dde
@@ -27,6 +27,7 @@ Do not implement inbound module interfaces in this plan. Include all concrete in
- `ShopeeInboundApiHandler` exists but has no outbound cases implemented.
- Confirmed: `4.2`-`4.5` Vendor-to-WES inventory/rack-transfer interfaces all enter WES through `ShopeeInboundApiHandler`; the handler then reuses existing `wms-transfer` and `wms-inventory` services.
- Confirmed: WES-to-Vendor basic-data interfaces in `5.2`-`5.8` are driven by scheduled jobs using a three-step `.confirm` -> `.get` -> `.uploadStatus` flow. Protocol `5.5` remains Vendor-to-WES and is not part of that scheduled outbound flow.
- Confirmed: Shopee extension fields are persisted through the dictionary mechanism only. Do not add WES entity columns for Shopee-only fields; use different dictionary group types for different usage locations.
- `ShipmentHeader` already contains key Shopee fields: `cutOffTime`, `purchaseTime`, `orderTime`, `shopeeWave`, `waveRule`, `kickOutWave`, `ticketType`, `pickType`, `orderStructure`, `groupKey`.
- `ShopeeWaveService` has low-water scheduling and persistence, but the actual upstream wave-number request is still a placeholder.
- `WaveRuleMatchService` has Shopee wave binding placeholders and local binding/rollback logic.
@@ -411,15 +412,15 @@ Map fields:
| `ship_by_date` | `shipment_header.scheduledShipDate` |
| `purchase_time` | `shipment_header.purchaseTime` |
| `order_time` | `shipment_header.orderTime` |
| `ctime` | if no dedicated WES field exists, do not add one; keep request log only |
| `can_group_picking` | do not add a field until confirmed; current `ShipmentHeader` has no field |
| `ctime` | dictionary only if business needs query/display; otherwise request log only |
| `can_group_picking` | dictionary only |
| `group_key` | `shipment_header.groupKey` |
| `ticket_type` | `shipment_header.ticketType`; `shipmentType` defaults to `XSCK` |
| `max_order_size` attr | `shipment_header.orderSize` only if field exists before implementation; otherwise map through rule dictionary |
| `channel_id` attr | `shipment_header.channelId` only if field exists before implementation; otherwise map through rule dictionary |
| `fulfillment_chain_id` attr | `shipment_header.fulfillmentChainId` only if field exists before implementation; otherwise map through rule dictionary |
| `max_order_size` attr | dictionary only |
| `channel_id` attr | dictionary only |
| `fulfillment_chain_id` attr | dictionary only |
Use existing fields only. If a field is not present in `ShipmentHeader.groovy` at execution time, do not add it just for convenience; write it into the existing Shopee field dictionary flow if available, or document the gap.
Use WES entity fields only for existing core business facts already present in the domain. All Shopee-only extension attributes go through the dictionary mechanism, not new columns.
- [ ] **Step 2: Implement idempotency**
@@ -444,9 +445,22 @@ For each `sku_info_list` row:
Validate SKU existence by reusing existing item/detail service behavior. Do not hand-roll item master queries if a service already validates item code.
- [ ] **Step 4: Map attributes to dictionary**
- [ ] **Step 4: Map all Shopee extension attributes to dictionary**
For `single_attr_list` and `multi_attr_list`, write missing values to the existing field dictionary mechanism if it exists. If no `shopee_field_dictionary` table/service exists in the current branch, create a separate migration only after confirming the table is absent:
For `single_attr_list`, `multi_attr_list`, and Shopee-only scalar fields, write values to the existing field dictionary mechanism. Different usage locations must use different dictionary group types so downstream logic can distinguish meaning.
Minimum group type split:
| Usage location | Dictionary group type |
| --- | --- |
| Outbound sales/sub-picking task header attrs | `SHOPEE_OUTBOUND_TASK_HEADER` |
| Outbound order attrs | `SHOPEE_OUTBOUND_ORDER_HEADER` |
| RTS/MTO demand attrs | `SHOPEE_RTSMTO_DEMAND_HEADER` |
| MTO picking task attrs | `SHOPEE_MTO_TASK_HEADER` |
| Inventory/rack-transfer attrs | `SHOPEE_RACK_TRANSFER_HEADER` |
| Basic-data sync attrs | `SHOPEE_BASIC_DATA` |
If no compatible dictionary table/service exists in the current branch, add a separate dictionary task before implementation; do not add Shopee-only fields to WES domain entities:
```powershell
rg -n "shopee_field_dictionary|FieldDictionary|field_dictionary" C:\work\gitlab\shopee\wes-loghub
@@ -1161,6 +1175,6 @@ Update:
## Self-Review
- Spec coverage: Covers `edi-shopee` as Shopee-facing entry, WES field mapping, wave number request, wave binding, all concrete interfaces from `3.1`-`3.4`, `4.1`-`4.7`, and `5.1`-`5.8`, JWT ownership in `edi-shopee`, and verification.
- Scope control: Excludes inbound module interfaces; includes outbound, inventory/rack-transfer, and basic-data interfaces from this protocol file; avoids adding fields unless absent fields are explicitly confirmed as required.
- Scope control: Excludes inbound module interfaces; includes outbound, inventory/rack-transfer, and basic-data interfaces from this protocol file; Shopee extension fields do not add WES entity columns and are persisted through dictionary group types.
- Type consistency: DTO names and handler method names match task references.
- Confirmed entry contract: Shopee 调 `edi-shopee``edi-shopee` 再转发到 WES `/api/wms/api/sync/in?api=shopee...`WES 不直接作为 Shopee 外部入口。