feat(t239): persist freight item metadata

This commit is contained in:
QiuSW
2026-07-29 14:54:58 +08:00
parent 42006acedb
commit 3bd9726ddc
23 changed files with 476 additions and 158 deletions
+25 -16
View File
@@ -728,6 +728,9 @@ func (service *FreightService) normalize(
!validBytes(sourceItem.ProductSpec, 1024) ||
!validBytes(sourceItem.SKU, 512) ||
!validOptional(sourceItem.ProductThumbRef, 512) ||
sourceItem.OriginalCurrency != domain.FreightCurrencyTWD ||
(sourceItem.OriginalUnitPriceMinor != nil &&
*sourceItem.OriginalUnitPriceMinor < 0) ||
!validOptional(sourceItem.PurchaseStatus, 128) ||
(sourceItem.Quantity != nil && *sourceItem.Quantity <= 0) {
return domain.FreightImportBatch{}, errors.New("invalid freight item fields")
@@ -737,26 +740,32 @@ func (service *FreightService) normalize(
return domain.FreightImportBatch{}, err
}
item := domain.FreightImportItem{
ID: itemID,
ExternalItemID: itemExternalID,
Title: sourceItem.Title,
ProductSpec: sourceItem.ProductSpec,
SKU: sourceItem.SKU,
Quantity: sourceItem.Quantity,
ProductThumbRef: cleanOptional(sourceItem.ProductThumbRef),
PurchaseStatus: cleanOptional(sourceItem.PurchaseStatus),
ID: itemID,
ExternalItemID: itemExternalID,
Title: sourceItem.Title,
ProductSpec: sourceItem.ProductSpec,
SKU: sourceItem.SKU,
Quantity: sourceItem.Quantity,
ProductThumbRef: cleanOptional(sourceItem.ProductThumbRef),
OriginalUnitPriceMinor: sourceItem.OriginalUnitPriceMinor,
OriginalCurrency: sourceItem.OriginalCurrency,
PurchaseStatus: cleanOptional(sourceItem.PurchaseStatus),
}
item.CanonicalSHA256 = hashJSON(struct {
ExternalItemID string `json:"external_item_id"`
Title string `json:"title"`
ProductSpec string `json:"product_spec"`
SKU string `json:"sku"`
Quantity *int `json:"quantity"`
ProductThumbRef *string `json:"product_thumb_ref"`
PurchaseStatus *string `json:"purchase_status"`
ExternalItemID string `json:"external_item_id"`
Title string `json:"title"`
ProductSpec string `json:"product_spec"`
SKU string `json:"sku"`
Quantity *int `json:"quantity"`
ProductThumbRef *string `json:"product_thumb_ref"`
OriginalUnitPriceMinor *int64 `json:"original_unit_price_minor"`
OriginalCurrency string `json:"original_currency"`
PurchaseStatus *string `json:"purchase_status"`
}{
item.ExternalItemID, item.Title, item.ProductSpec, item.SKU,
item.Quantity, item.ProductThumbRef, item.PurchaseStatus,
item.Quantity, item.ProductThumbRef,
item.OriginalUnitPriceMinor, item.OriginalCurrency,
item.PurchaseStatus,
})
order.Items = append(order.Items, item)
}
@@ -33,6 +33,19 @@ func TestFreightNormalizationHashExcludesInternalIDs(t *testing.T) {
second.Orders[0].CanonicalSHA256,
)
}
changed := validFreightSource()
changedPrice := *changed.Orders[0].Items[0].OriginalUnitPriceMinor + 1
changed.Orders[0].Items[0].OriginalUnitPriceMinor = &changedPrice
changedBatch, err := firstService.normalize(changed)
if err != nil {
t.Fatalf("changed price normalize error = %v", err)
}
if first.Orders[0].CanonicalSHA256 ==
changedBatch.Orders[0].CanonicalSHA256 ||
first.Orders[0].Items[0].CanonicalSHA256 ==
changedBatch.Orders[0].Items[0].CanonicalSHA256 {
t.Fatal("canonical hash ignored original unit price")
}
}
func TestFreightNormalizationRejectsConflictingIdentityAndInvalidTime(
@@ -466,6 +479,7 @@ func validFreightSource() domain.FreightSourceBatch {
thumb := "190"
itemPurchaseStatus := "0"
quantity := 2
originalUnitPriceMinor := int64(12950)
canceled := false
return domain.FreightSourceBatch{
SchemaVersion: 1,
@@ -481,13 +495,15 @@ func validFreightSource() domain.FreightSourceBatch {
PurchaseStatus: &purchaseStatus,
IsCanceled: &canceled,
Items: []domain.FreightSourceItem{{
ExternalItemID: "88",
Title: "商品",
ProductSpec: "黑色,L",
SKU: "BLACK-L",
Quantity: &quantity,
ProductThumbRef: &thumb,
PurchaseStatus: &itemPurchaseStatus,
ExternalItemID: "88",
Title: "商品",
ProductSpec: "黑色,L",
SKU: "黑色,L",
Quantity: &quantity,
ProductThumbRef: &thumb,
OriginalUnitPriceMinor: &originalUnitPriceMinor,
OriginalCurrency: domain.FreightCurrencyTWD,
PurchaseStatus: &itemPurchaseStatus,
}},
}},
}