feat(bom): canonical lot mappings and updated vendor spec docs

This commit is contained in:
Mikhail Chusavitin
2026-02-25 19:07:27 +03:00
parent aa65fc8156
commit e9230c0e58
7 changed files with 967 additions and 188 deletions

View File

@@ -678,6 +678,7 @@ func (h *SyncHandler) ReportPartnumberSeen(c *gin.Context) {
Items []struct {
Partnumber string `json:"partnumber"`
Description string `json:"description"`
Ignored bool `json:"ignored"`
} `json:"items"`
}
if err := c.ShouldBindJSON(&body); err != nil {
@@ -691,6 +692,7 @@ func (h *SyncHandler) ReportPartnumberSeen(c *gin.Context) {
items = append(items, sync.SeenPartnumber{
Partnumber: it.Partnumber,
Description: it.Description,
Ignored: it.Ignored,
})
}
}

View File

@@ -283,6 +283,21 @@ type VendorSpecItem struct {
ResolvedLotName string `json:"resolved_lot_name,omitempty"`
ResolutionSource string `json:"resolution_source,omitempty"` // "book", "manual", "unresolved"
ManualLotSuggestion string `json:"manual_lot_suggestion,omitempty"`
LotQtyPerPN int `json:"lot_qty_per_pn,omitempty"`
LotAllocations []VendorSpecLotAllocation `json:"lot_allocations,omitempty"`
LotMappings []VendorSpecLotMapping `json:"lot_mappings,omitempty"`
}
type VendorSpecLotAllocation struct {
LotName string `json:"lot_name"`
Quantity int `json:"quantity"` // quantity of LOT per 1 vendor PN
}
// VendorSpecLotMapping is the canonical persisted LOT mapping for a vendor PN row.
// It stores all mapped LOTs (base + bundle) uniformly.
type VendorSpecLotMapping struct {
LotName string `json:"lot_name"`
QuantityPerPN int `json:"quantity_per_pn"`
}
// VendorSpec is a JSON-encodable slice of VendorSpecItem

View File

@@ -10,6 +10,7 @@ import (
type SeenPartnumber struct {
Partnumber string
Description string
Ignored bool
}
// PushPartnumberSeen inserts unresolved vendor partnumbers into qt_vendor_partnumber_seen on MariaDB.
@@ -31,13 +32,14 @@ func (s *Service) PushPartnumberSeen(items []SeenPartnumber) error {
}
err := mariaDB.Exec(`
INSERT INTO qt_vendor_partnumber_seen
(source_type, vendor, partnumber, description, last_seen_at)
(source_type, vendor, partnumber, description, is_ignored, last_seen_at)
VALUES
('manual', '', ?, ?, ?)
('manual', '', ?, ?, ?, ?)
ON DUPLICATE KEY UPDATE
last_seen_at = VALUES(last_seen_at),
is_ignored = VALUES(is_ignored),
description = COALESCE(NULLIF(VALUES(description), ''), description)
`, item.Partnumber, item.Description, now).Error
`, item.Partnumber, item.Description, item.Ignored, now).Error
if err != nil {
slog.Error("failed to upsert partnumber_seen", "partnumber", item.Partnumber, "error", err)
// Continue with remaining items