From ad2921b4a01cbcc8a4736af6f571f646b4da95f3 Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Mon, 29 Jun 2026 08:38:56 -0400 Subject: [PATCH] fix(tags): allow creating a same-named character in a different fandom MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The autocomplete suppressed the Create row whenever any existing tag matched name+kind — but characters are unique by (name, kind, fandom), so a same-named character in a different fandom (e.g. another "Raven") is a valid distinct tag. allowCreate now always offers Create for the character kind; the fandom picker disambiguates and find_or_create is idempotent if the same fandom is re-picked. The Create row reads "Create another \"Raven\" character (different fandom)" when a same-name character already exists. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01Ttrj5P7upUTueSfoJcxEqa --- .../src/components/modal/TagAutocomplete.vue | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/frontend/src/components/modal/TagAutocomplete.vue b/frontend/src/components/modal/TagAutocomplete.vue index 43ab0e1..65f3527 100644 --- a/frontend/src/components/modal/TagAutocomplete.vue +++ b/frontend/src/components/modal/TagAutocomplete.vue @@ -72,7 +72,7 @@ - Create "{{ parsedName }}" as {{ parsedKind }} + {{ createLabel }} @@ -178,14 +178,34 @@ watch(query, () => { }, 200) }) +// A same-name character ALREADY exists. Characters are unique by +// (name, kind, fandom), so this is still a valid distinct tag in another fandom. +const sameNameCharExists = computed(() => + parsedKind.value === 'character' && + hits.value.some(h => + h.kind === 'character' && h.name.toLowerCase() === parsedName.value.toLowerCase(), + ), +) + const allowCreate = computed(() => { const q = parsedName.value if (!q) return false + // Characters disambiguate by fandom, so a same-named character in a DIFFERENT + // fandom is a valid new tag — always offer Create (the fandom picker resolves + // it; find_or_create is idempotent if you re-pick the same fandom). Other + // kinds are unique by (name, kind): an exact match means it already exists. + if (parsedKind.value === 'character') return true return !hits.value.some(h => h.name.toLowerCase() === q.toLowerCase() && h.kind === parsedKind.value, ) }) +const createLabel = computed(() => + sameNameCharExists.value + ? `Create another "${parsedName.value}" character (different fandom)` + : `Create "${parsedName.value}" as ${parsedKind.value}`, +) + function scorePct (s) { return `${Math.round(s.score * 100)}%` } // This image's suggestions that match the typed query, minus any the server