feat(inventory-go): wire spell filters into /search/items; harden empty-input guards

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Erik 2026-07-14 23:53:38 +02:00
parent 4edf94f416
commit 7096f30566
3 changed files with 23 additions and 3 deletions

View file

@ -302,6 +302,9 @@ func (s *Server) runSearch(ctx context.Context, q url.Values) (map[string]any, e
}
}
// --- spell filters: has_spell / spell_contains / legendary_cantrips ---
conds = append(conds, spellFilterConds(q, s.spells, ab)...)
where := ""
if len(conds) > 0 {
where = " WHERE " + strings.Join(conds, " AND ")

View file

@ -53,6 +53,9 @@ func exactSpellID(spells map[int]map[string]any, q string) (int, bool) {
best := -1
for id, sp := range spells {
name, _ := sp["name"].(string)
if name == "" {
continue
}
if strings.ToLower(name) == q && (best == -1 || id < best) {
best = id
}
@ -79,21 +82,21 @@ func spellFilterConds(q url.Values, spells map[int]map[string]any, ab *argBuilde
var conds []string
impossible := func() { conds = append(conds, "1 = 0") }
if v := q.Get("has_spell"); v != "" {
if v := strings.TrimSpace(q.Get("has_spell")); v != "" {
if id, ok := exactSpellID(spells, v); ok {
conds = append(conds, spellExists([]int{id}, ab))
} else {
impossible()
}
}
if v := q.Get("spell_contains"); v != "" {
if v := strings.TrimSpace(q.Get("spell_contains")); v != "" {
if ids := spellIDsContaining(spells, v); len(ids) > 0 {
conds = append(conds, spellExists(ids, ab))
} else {
impossible()
}
}
if v := q.Get("legendary_cantrips"); v != "" {
if v := strings.TrimSpace(q.Get("legendary_cantrips")); v != "" {
for _, name := range splitNonEmpty(v) {
if ids := spellIDsForCantrip(spells, name); len(ids) > 0 {
conds = append(conds, spellExists(ids, ab))

View file

@ -112,3 +112,17 @@ func TestSpellFilterConds_Empty(t *testing.T) {
t.Errorf("no params => nil conds, got %v", conds)
}
}
func TestSpellFilterConds_WhitespaceParamsIgnored(t *testing.T) {
ab := &argBuilder{}
q := map[string][]string{"spell_contains": {" "}, "has_spell": {" "}, "legendary_cantrips": {" , "}}
if conds := spellFilterConds(q, testSpells, ab); conds != nil {
t.Errorf("whitespace params => nil conds, got %v", conds)
}
}
func TestExactSpellID_EmptyNeverMatchesMalformed(t *testing.T) {
if _, ok := exactSpellID(testSpells, ""); ok {
t.Error("empty query must not match the malformed empty-name entry")
}
}