9276b31b99
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>