Commit Graph

14 Commits

Author SHA1 Message Date
bvandeusen a510665a17 feat(suggestions): user-managed blocklist for noisy auto-tags
Adds a tag_suggestion_blocklist table + service-layer filter so the
user can permanently suppress specific canonical tag names from the
suggestion stream (WD14 anatomy/composition tags like '1girl',
'breasts', 'nipples' that aren't useful for the discoverability use
case this app targets).

Data model
  - migration k26042201: tag_suggestion_blocklist(name TEXT PK, created_at)
  - model TagSuggestionBlocklistEntry

Service
  - tag_suggestions._blocklisted_names() snapshots the current set
  - get_suggestions filters merged results before grouping, so both
    WD14- and embedding-sourced suggestions respect the blocklist
  - get_bulk_suggestions inherits the filter via its per-image call
    to get_suggestions

API
  - GET  /api/suggestions/blocklist           -> {ok, names}
  - POST /api/suggestions/blocklist           -> add one
  - POST /api/suggestions/blocklist/delete    -> remove one
  - POST /api/suggestions/blocklist/bulk      -> replace the whole list
    (backs the settings textarea save button)

UI
  - modal suggestion chip gets a third action button (⊘) alongside
    accept (✓) / reject (✕). Clicking it adds the name to the
    blocklist, logs a rejection for ML feedback on this image, and
    sweeps every chip on the page carrying that same name.
  - Settings -> Maintenance -> Suggestion blocklist section with a
    monospaced textarea (one name per line) + Save. Loads current
    entries on mount.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-23 08:41:44 -04:00
bvandeusen fc70d56afb fix(migration): drop tag_name_key up front; merge Phase 1 collisions
The original Phase 3 dropped the legacy global UNIQUE(tag.name) at the end,
which meant Phase 1's prefix-strip UPDATEs ran with the old constraint still
in place. On any DB that had a pre-existing bare-name row colliding with the
stripped form of a prefixed row (e.g. 'character:Marcille Donato' stripping
to 'Marcille Donato' where another 'Marcille Donato' already existed), the
migration blew up with UniqueViolation on tag_name_key.

Fix: drop tag_name_key at the very top of upgrade() so both phases operate
against a uniqueness-free table. Add explicit collision handling to Phase 1
(mirrors the existing Phase 2 auto-merge): when the stripped name already
matches an existing row under the shape of the incoming partial-index
(same kind, or same kind+fandom_id for characters), reassign image_tags
onto the winner, cascade-rename tag_reference_embedding, and delete the
loser. Report now shows phase1_merged alongside phase1_renames.

Backwards-compatible for DBs where the failing migration already rolled
back — rerunning picks up the fix. The migration's transaction atomicity
means the DB is still in pre-migration state after the earlier failure.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-22 17:35:05 -04:00
bvandeusen e2df0aa675 chore: prune stale migration __pycache__ entries
These .pyc files were already deleted on disk; the working tree just
hadn't staged the removals. No behavioral change.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-22 17:27:30 -04:00
bvandeusen c7e2605a10 feat(migration): bare tag names; fandom_id authoritative
Three-phase Alembic migration j26042101 strips 'kind:' prefix from every
non-user tag, extracts character '(Fandom)' suffix into fandom_id with
auto-merge on duplicates, and swaps UNIQUE(name) for four partial indices
keyed on (name, kind) with special handling for the (character, fandom_id)
combination.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-22 09:39:36 -04:00
bvandeusen 0f35a0c484 feat: ML tag suggestions, character/fandom integrity, underscores, modal polish
Consolidated merge of feat/tag-suggestions branch. Original 64-commit history
was lost to git-object corruption in a Nextcloud-synced checkout; this single
commit captures the equivalent diff.

Includes:
- pgvector-backed tag suggestion infra (WD14 + SigLIP centroids, ml-worker
  container, Celery tasks, suggestion service, accept/reject endpoints + modal
  UI with green/red chip buttons)
- Character/fandom integrity: title-case normalization on every write path,
  fandom-id backfill, maintenance task + settings button, migrations g26041901
  + h26041901 to canonicalize legacy rows with case-only duplicate merging
- Tag-underscores + modal polish: WD14 name canonicalization at emit + accept
  + add/bulk-add paths, migration i26041901 for legacy-row rename-or-merge
  across character/fandom/NULL kinds, suggestion-accept refresh parity via
  awaited loadTags, persistent chip tint
2026-04-19 19:50:58 -04:00
bvandeusen bf20eeab5c character-fandom tag association system
Link character tags to fandom tags via fandom_id FK with auto-apply
behavior. Adding character:Saber (Fate) auto-creates fandom:Fate and
applies it to the image. Renaming a fandom cascades to all linked
characters. Includes set-fandom endpoint for retroactive association
and fandom selector dropdown in the tag editor UI.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 19:53:02 -05:00
Bryan Van Deusen a05aee5a07 implement post metadata import and views. implemented series paging and reader view. 2026-01-22 22:19:11 -05:00
Bryan Van Deusen cb3897c0b0 changes to mobile styling in modal view, complete reword of backend worker system 2026-01-20 13:14:13 -05:00
Bryan Van Deusen 96f72718bd moving styling and views to be more consistent and for gallery view to be less cumbersome. 2026-01-19 23:41:36 -05:00
Bryan Van Deusen 3ff34ec9c2 switched to tagging and added views to support it, in progress for other tagging functions. 2025-08-14 21:36:27 -04:00
Bryan Van Deusen e9793ba38c polish on archive import processing 2025-08-14 16:19:16 -04:00
Bryan Van Deusen 63918363c1 improved Modal with zoom and pagination. also implementing thumbnail generation 2025-08-01 23:19:17 -04:00
Bryan Van Deusen c67f1afc1f initial functionality and styling pass 2025-07-29 00:34:03 -04:00
bvandeusen d200550b35 Initial commit 2025-07-28 21:57:49 +00:00