From 50360f72c42142ff1503fe7fcda244a687be5a8b Mon Sep 17 00:00:00 2001 From: Erik Date: Wed, 24 Jun 2026 12:02:17 +0200 Subject: [PATCH] =?UTF-8?q?feat(go-services):=20inventory-go=20search=20?= =?UTF-8?q?=E2=80=94=20name/material/set=20enrichment=20(exact)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit enrichRows now applies the material-name prefix to name (material is already a translated string in the DB), sets material_name + original_name, and resolves item_set_name via the AttributeSetInfo enum (fallback "Set {id}"). Validated vs Python position-by-position: 0 mismatches across 60 armor + 60 jewelry rows for name, material_name, item_set_name, original_name, value, object_class. Sample names match exactly (e.g. "Gold Alduressa Coat"). Remaining enrichment slices: object_class_name (gem context), spells/spell_names (needs the spells enum map), slot_name (sophisticated), weapon damage/speed/mana, rating gear-total fallbacks. Co-Authored-By: Claude Opus 4.8 --- go-services/inventory-go/search.go | 41 ++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/go-services/inventory-go/search.go b/go-services/inventory-go/search.go index b0db7b37..68f5ab8d 100644 --- a/go-services/inventory-go/search.go +++ b/go-services/inventory-go/search.go @@ -325,10 +325,7 @@ func (s *Server) handleSearchItems(w http.ResponseWriter, r *http.Request) { return } - items := make([]map[string]any, 0, len(rows)) - for _, row := range row2items(rows) { - items = append(items, row) - } + items := s.enrichRows(rows) writeJSON(w, http.StatusOK, map[string]any{ "items": items, @@ -340,13 +337,14 @@ func (s *Server) handleSearchItems(w http.ResponseWriter, r *http.Request) { }) } -// row2items applies the direct-column transforms (computed booleans, condition, -// timestamp formatting) and strips internal columns. Deep enrichment is a later -// slice. -func row2items(rows []map[string]any) []map[string]any { +// enrichRows applies the direct-column transforms (computed booleans, condition, +// timestamp), the material-name prefix, and the item_set name, then strips +// internal columns. Deeper enrichment (spells, slot_name, weapon damage/mana, +// rating fallbacks) is a later slice. +func (s *Server) enrichRows(rows []map[string]any) []map[string]any { + out := make([]map[string]any, 0, len(rows)) for _, row := range rows { - cw := toInt64(row["current_wielded_location"]) - row["is_equipped"] = cw > 0 + row["is_equipped"] = toInt64(row["current_wielded_location"]) > 0 row["is_bonded"] = toInt64(row["bonded"]) > 0 row["is_attuned"] = toInt64(row["attuned"]) > 0 row["is_rare"] = toInt64(row["rare_id"]) > 0 @@ -359,9 +357,30 @@ func row2items(rows []map[string]any) []map[string]any { if t, ok := row["last_updated"].(time.Time); ok { row["last_updated"] = pyISO(t) } + + // material_name + material prefix on name (material is already a + // translated string in the DB; enrich_db_item:2371-2602). + if mat := toStr(row["material"]); mat != "" { + row["material_name"] = mat + if name := toStr(row["name"]); name != "" && + !strings.HasPrefix(strings.ToLower(name), strings.ToLower(mat)) { + row["original_name"] = name + row["name"] = mat + " " + name + } + } + // item_set_name (enrich_db_item:2551-2562). + if iset := strings.TrimSpace(toStr(row["item_set"])); iset != "" { + if n, ok := s.attributeSets[iset]; ok { + row["item_set_name"] = n + } else { + row["item_set_name"] = "Set " + iset + } + } + delete(row, "db_item_id") + out = append(out, row) } - return rows + return out } // translateSetID mirrors translate_equipment_set_id (AttributeSetInfo lookup,