bvandeusen
f657582f30
feat(import-ui): deep scan button, sticky settings tabs, tasks-above-filters, fix Scanning-undefined source_path — Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 17:37:10 -04:00
bvandeusen
b6a917ac81
feat(import): /api/import/clear-stuck endpoint + Clear stuck UI button — escape hatch for the autoretry-loop case the automatic sweep can't break
...
Operator hit 3 large PNGs stuck in 'processing' for 2 days 2026-05-25:
the existing recover_interrupted_tasks flips processing > 5min back to
queued + .delay(), but if the underlying file is unfixably broken (e.g.,
PIL OSError, also patched in 68cffce ), the loop never terminates and the
'Scanning...' banner sticks at 0/0 forever blocking new scans.
/api/import/clear-stuck:
- Flips every task in pending/queued/processing to 'failed' with a clear
marker error message
- Finalizes any 'running' ImportBatch that has no remaining active children
- Idempotent + non-destructive: rows survive, can be retried once the
underlying cause is resolved
UI button 'Clear stuck...' sits next to 'Retry failed' / 'Clear completed'
with a warning-tonal alert in the confirm dialog explaining what it does
and recommending Retry failed once the cause is fixed.
Tests: clears mixed non-terminal states, untouches complete rows,
finalizes orphan batch, no-op when nothing stuck.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-25 12:37:07 -04:00
bvandeusen
c361032554
feat(gallery): sort/group/jump by COALESCE(post.post_date, image_record.created_at) — surface migrated content at its original publish date, not FC scan date
...
Operator hit this 2026-05-25 after the IR tag_apply landed: ~57k images
all scanned into FC in the same week share image_record.created_at, so
the gallery timeline collapses them into a single month bucket and
scroll orders them all together at the top. Their actual publish dates
(spread over years) were already available in Post.post_date but the
gallery never read it.
Backend wire-up:
- tag_apply phase 4 now sets ImageRecord.primary_post_id when creating
ImageProvenance (only if currently NULL — preserves the canonical
download-time linkage set by the importer for new FC ingests).
- gallery_service.py introduces _effective_date_col() =
COALESCE(post.post_date, image_record.created_at), used in:
* scroll() ORDER BY + cursor WHERE clauses
* timeline() year/month group-by
* jump_cursor() year/month filter
* _neighbors() prev/next ordering
- Each method LEFT OUTER JOIN Post on primary_post_id so the COALESCE
works for images without a post (NULL on the Post side, fall back
to created_at).
- GalleryImage gains posted_at + effective_date fields; API /gallery
/scroll exposes both alongside the existing created_at so the UI
can render 'Posted on X (imported Y)' if desired.
- get_image_with_tags() returns posted_at for the modal.
Cursor format unchanged — the encoded datetime is now the effective_
date (whichever column won the COALESCE) and pagination remains
consistent.
To pick up new behavior for an already-migrated IR set: re-run
/api/migrate/tag_apply on the existing manifest (phase 4 is
idempotent; the new primary_post_id assignment backfills).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-25 12:30:18 -04:00
bvandeusen
f096c9a5fb
fc3k: register admin_bp in api/__init__ all_blueprints
...
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-25 00:42:40 -04:00
bvandeusen
676a86b514
fc3k: /api/admin tags prune-unused endpoint — Tier-A preview-then-commit flow
...
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-25 00:42:20 -04:00
bvandeusen
44cc625d4a
fc3k: /api/admin tag endpoints — Tier-B delete + merge + usage-count helper
...
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-25 00:42:03 -04:00
bvandeusen
f7ee122243
fc3k: /api/admin blueprint — Tier-C artist cascade + bulk image delete with sha8-keyed confirm tokens
...
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-25 00:40:53 -04:00
bvandeusen
718cc79905
fix(fc3h): split semicolon-stacked statements (E702) and bridge v-dialog v-model to avoid prop write
...
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-24 23:37:06 -04:00
bvandeusen
d3d4320ed5
fc3h: retire backup + rollback from migrate API/task — moved to /api/system/backup/* per FC-3h
...
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-24 22:59:11 -04:00
bvandeusen
7d42cddb11
fc3h: /api/system/backup blueprint — trigger, list, get, patch, restore, delete, settings
...
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-24 22:57:25 -04:00
bvandeusen
541e2bfe6a
fc3i: /api/system/activity blueprint — queues, workers, runs, failures
...
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-24 21:04:34 -04:00
bvandeusen
553567738e
fix: drop migration backup-gate (FC-3h supersedes) + modal Escape via document-level listener so video focus can't swallow it
...
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-24 14:38:33 -04:00
bvandeusen
96039fc983
fix(ext): wrap /api/extension/manifest filesystem work in asyncio.to_thread (ruff ASYNC240)
...
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-24 12:20:36 -04:00
bvandeusen
2065672a31
fc3g: /api/extension blueprint — quick-add-source + manifest endpoints, registered
...
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-23 23:38:35 -04:00
bvandeusen
7a5a71471e
fix(scan): auto-finalize empty scans + system_stats picks running batch with actual work
...
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-23 21:25:57 -04:00
bvandeusen
f5efbea053
feat(fc5): /api/migrate/cleanup — delete every image attributed to one artist, files + thumbs + DB
...
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-23 12:09:56 -04:00
bvandeusen
6f68bf5fa7
feat(ui): bump thumbnail sizes 1.5x, make Settings fluid, add subscription_count stat
...
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-22 23:18:22 -04:00
bvandeusen
89224a7895
fc5: /api/migrate blueprint — multipart upload for ingest kinds + JSON for the rest + apply-without-backup guard
...
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-22 09:03:24 -04:00
bvandeusen
51bdaf167b
fc3f: GET /api/artists/directory — cursor + q + platform filters with validation
...
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-21 22:14:42 -04:00
bvandeusen
266137e3d0
fc3e: /api/posts blueprint — list (with cursor + filters) + detail
...
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-21 18:55:18 -04:00
bvandeusen
28a4ed3d38
fc3d: settings API exposes scheduling knobs with bounds validation
...
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-21 16:04:19 -04:00
bvandeusen
e9814ca7e4
feat(fc3c): expose download_rate_limit_seconds + download_validate_files in /api/settings/import
...
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-20 20:44:58 -04:00
bvandeusen
71e6114f49
feat(fc3c): /api/downloads blueprint (list + detail w/ keyset pagination)
...
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-20 20:44:28 -04:00
bvandeusen
95cfdff97d
feat(fc3c): POST /api/sources/<id>/check — enqueue download
...
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-20 20:43:48 -04:00
bvandeusen
6fe8d199a0
fix(fc3b): replace FC-3a KNOWN_PLATFORMS w/ registry; drop /api/sources/platforms
...
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-20 18:37:17 -04:00
bvandeusen
e77d976ff0
feat(fc3b): extension_api_key endpoints + create_app bootstraps credential key
...
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-20 18:36:28 -04:00
bvandeusen
617aa5a90a
feat(fc3b): /api/credentials blueprint (CRUD + X-Extension-Key auth)
...
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-20 18:35:54 -04:00
bvandeusen
ca8a27fee7
feat(fc3b): /api/platforms blueprint (read-only registry view)
...
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-20 18:34:23 -04:00
bvandeusen
bf828c7b9d
fix(fc3a): ruff I001 import-block fixes + use sqlalchemy.case (not func.case)
...
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-20 14:22:53 -04:00
bvandeusen
c415cb45d9
feat(fc3a): /api/artists POST + autocomplete
...
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-20 12:55:51 -04:00
bvandeusen
1e834c0139
feat(fc3a): /api/sources blueprint (CRUD + platforms endpoint)
...
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-20 12:55:27 -04:00
bvandeusen
c37a3c9b55
feat(integrity): /api/system/stats exposes integrity counts
...
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-19 17:53:12 -04:00
bvandeusen
389d1bb0cf
feat(integrity): /trigger accepts mode=verify → enqueues verify_integrity
...
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-19 17:52:18 -04:00
bvandeusen
9535533385
feat(deep-scan): trigger accepts 'deep'; scan_directory(mode) + enqueue backfill_phash
...
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-19 15:31:26 -04:00
bvandeusen
74e34d359b
feat(attachments): provenance payload attachments + download route
...
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-19 11:16:01 -04:00
bvandeusen
f6d5353b3b
feat(provenance): per-image artist on gallery scroll payload
...
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-18 20:15:07 -04:00
bvandeusen
1590447301
feat(provenance): post_id/artist_id gallery filters via EXISTS (mutually exclusive)
...
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-18 18:08:54 -04:00
bvandeusen
bb3fb5145a
feat(provenance): /api/provenance image + post endpoints
...
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-18 18:07:06 -04:00
bvandeusen
9ef5e5047d
feat(phash): import_settings.phash_threshold (migration 0006) exposed + validated in API
...
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-17 22:04:13 -04:00
bvandeusen
d8e585a76e
feat(series): /api/series pages/add/remove/reorder/cover routes
...
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-16 23:35:12 -04:00
bvandeusen
f946918cd2
feat(bulk): SuggestionService.for_selection consensus + POST /api/suggestions/bulk
...
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-16 18:03:16 -04:00
bvandeusen
e1c8400c87
feat(bulk): BulkTagService (common_tags/bulk_add/bulk_remove) + 3 image bulk-tag routes
...
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-16 18:02:01 -04:00
bvandeusen
93b6fc21c8
fix(tags): invalid 'copyright' kind 500 — KINDS uses real enum 'fandom'; directory 400s on bad kind
...
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-16 15:51:27 -04:00
bvandeusen
305687dc33
feat(api): rich 409 merge hint and POST tags merge endpoint with backfill enqueue
...
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-16 13:40:37 -04:00
bvandeusen
e43c2a0dd0
feat(fc2c-i): artist overview + paged images endpoints
2026-05-15 15:52:02 -04:00
bvandeusen
8484cb9aaa
feat(fc2c-i): tag directory service and /api/tags/directory
2026-05-15 15:50:41 -04:00
bvandeusen
a74b313596
feat(fc2c-i): showcase random-sample service and endpoint
2026-05-15 15:49:25 -04:00
bvandeusen
f7f75fcac6
refactor(fc2c-i): sweep blueprints + ml tasks onto shared get_session (covers tasks/ml.py, a survey gap)
2026-05-15 15:48:02 -04:00
bvandeusen
aa4cc7c629
feat(fc2b): add tag rename (PATCH /api/tags/<id>) + /api/ml admin
...
Rename returns 409 on collision (frontend shows FC-2c merge hint), 400
on empty. ml_admin: GET/PATCH settings (thresholds + min_reference;
model versions read-only here), POST backfill / recompute-centroids
returning 202 + celery task id. Tests integration-marked, eager Celery.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-15 07:54:12 -04:00
bvandeusen
46338a1f2e
feat(fc2b): add /api/allowlist and /api/aliases endpoints
...
Allowlist: list-all, get-one (404 if not listed), PATCH threshold
(range-validated), DELETE. Aliases: list-all (with canonical name),
create (idempotent, 201), DELETE by (string, category). Tests
integration-marked.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-15 07:46:38 -04:00