fix: артикул — распознавание DPU/BlueField профиля (BF3/BF2)

DPU-лоты (DPU_BF3_B3220-32G) не подходили под regex parsePortSpeed
(рассчитан на NIC/HCA-суффиксы NpMGbE/pFC) и падали в заглушку
категории NET с предупреждением. Добавлен parseDPUModel — структурный
разбор DPU_{FAMILY}_{MODEL} без каталога вендоров.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Mikhail Chusavitin
2026-09-17 11:56:42 +03:00
co-authored by Claude Sonnet 5
parent 37def17c5c
commit 006d7e87c5
2 changed files with 72 additions and 0 deletions
+19
View File
@@ -466,9 +466,28 @@ func parsePortSpeed(lotName string) string {
if m := rePortFC.FindStringSubmatch(lotName); len(m) == 3 {
return fmt.Sprintf("%spFC%s", m[1], m[2])
}
if model := parseDPUModel(lotName); model != "" {
return model
}
return ""
}
// parseDPUModel extracts the "{FAMILY}_{MODEL}" tail from a DPU lot_name (shape
// DPU_{FAMILY}_{MODEL}, e.g. "DPU_BF3_B3220-32G" -> "BF3_B3220-32G"). DPU lots have
// no port-speed suffix like NIC/HCA, so they fall through parsePortSpeed's regexes;
// this keeps the family prefix (e.g. BF2 vs BF3) so distinct DPU generations sharing
// a part-number suffix don't collapse into the same article token. Like parseCPUModel
// it does not validate against a vendor catalog, only matches the expected shape.
func parseDPUModel(lotName string) string {
upper := strings.ToUpper(lotName)
const prefix = "DPU_"
if !strings.HasPrefix(upper, prefix) {
return ""
}
rest := strings.TrimSpace(upper[len(prefix):])
return rest
}
func parseWatts(lotName string) string {
if m := reWatts.FindStringSubmatch(lotName); len(m) == 2 {
w := atoi(m[1])