From f3094ec24fa6f6349bae91dbd511566b7f657803 Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Sat, 25 Apr 2026 19:53:42 -0400 Subject: [PATCH] fix(autocomplete): parse kind:rest in /api/tags/search The add-tag input lets the user type 'character:mocha' as a kind shortcut, but the autocomplete was passing the whole query through to ilike, so '%character:mocha%' never matched any display_name. Use parse_kind_prefix to split the prefix into a kind filter, leaving the rest as the search term. An explicit ?kind= (e.g. fandom picker) still wins. Empty rest ('character:') falls into the no-query branch and shows top characters. Co-Authored-By: Claude Opus 4.7 --- app/main.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/app/main.py b/app/main.py index d610684..14cbb63 100644 --- a/app/main.py +++ b/app/main.py @@ -663,13 +663,26 @@ def search_tags(): - kind: filter to only include tags of this kind """ from sqlalchemy import case + from app.utils.tag_prefix import parse_kind_prefix - query = request.args.get("q", "").strip().lower() + raw_q = request.args.get("q", "").strip() limit = request.args.get("limit", 10, type=int) exclude_kind = request.args.get("exclude_kind", "").strip() exclude_kinds = [k.strip() for k in exclude_kind.split(",") if k.strip()] include_kind = request.args.get("kind", "").strip() + # Honour the same `kind:rest` shortcut the add-tag input uses, so typing + # "character:mocha" filters to character rows matching "mocha" instead of + # ilike-matching the literal "character:" string against display_name. + # An explicit ?kind= still wins (used by the fandom picker). + if not include_kind: + parsed_kind, parsed_rest = parse_kind_prefix(raw_q) + if parsed_kind is not None: + include_kind = parsed_kind + raw_q = parsed_rest + + query = raw_q.lower() + f = aliased(Tag) display_expr = case( (