feat(maintenance): backfill fandom tags onto legacy character attachments

New Celery task sync_character_fandoms_to_images on the maintenance
queue. For every character tag with a non-null fandom_id, runs the
same INSERT ... SELECT ... ON CONFLICT DO NOTHING that set_tag_fandom
already runs inline, attaching the fandom tag to every image that
has the character attached.

Why this exists: migration j26042101 extracted the '(Fandom)' suffix
from pre-refactor character names into tag.fandom_id, but it did NOT
walk image_tags to attach the fandom rows to every image that had
the character. Post-refactor auto-apply (in add_tag /
accept_image_suggestion / set_tag_fandom) only fires on NEW
add/accept events — pre-existing character attachments from before
the migration still show the character pill in the modal but no
fandom pill, because the fandom row was never added to image_tags.

Surfaced by Settings → Maintenance → 'Sync fandoms to images'.
Safe, additive, idempotent. Run once after the migration to close
the gap; subsequent set-fandom operations continue to maintain the
invariant inline.

Verified locally: seeded a character+fandom pair with only the
character attached to image 1; task added the fandom to image_tags;
final state has both rows.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-04-24 08:58:51 -04:00
parent 3b472cf519
commit 9276b31b99
4 changed files with 84 additions and 0 deletions
+7
View File
@@ -641,6 +641,13 @@ def trigger_recompute_all_centroids():
return redirect(url_for('main.settings', tab='maintenance'))
@main.post('/settings/maintenance/sync-character-fandoms-to-images')
def trigger_sync_character_fandoms_to_images():
from app.tasks.maintenance import sync_character_fandoms_to_images
sync_character_fandoms_to_images.apply_async(queue='maintenance')
return redirect(url_for('main.settings', tab='maintenance'))
# ----------------------------
# Tag add/remove endpoints
# ----------------------------