Single-file pipeline: validate as image, apply filter rules (min dimensions,
transparency), SHA256 hash dedup, atomic copy to /images/{subdir}/, create
ImageRecord with origin='imported_filesystem' and integrity_status='unknown',
auto-derive top-level folder name as Artist + artist tag.
Importer is intentionally sync (consumed by a Celery worker process); the
async Quart side uses the same ORM through its own async session. The
db_sync fixture in conftest.py was added in Task 3 to support these tests.
Thumbnail generation is NOT inlined; the calling Celery task enqueues a
separate thumbnail task so the import queue keeps moving on big batches.
pHash dedup is FC-2d, not here.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Generates 400px-max thumbnails: PNG with alpha preserved when source has
transparency, JPEG (q=85, progressive) otherwise. Storage layout is
/images/thumbs/{sha[:3]}/{sha}.{jpg|png} so each prefix bucket holds at
most ~4k files (16^3 buckets across all possible SHAs).
Video path uses ffmpeg's first-frame snapshot at ~5% offset; we have a
1-second floor for short clips. ffmpeg call has a 60s timeout. Video
tests are deferred to FC-2e's integration suite where transcoding is
also wired up.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Validates kind/fandom rules at the service layer: fandom_id only allowed
for kind='character', and must reference an existing kind='fandom' tag.
Autocomplete ranking: exact match > prefix match > substring, tie-broken
by image_count descending. Image-tag association uses INSERT ON CONFLICT
DO NOTHING for idempotent re-tagging.
conftest.py adds a transactional AsyncSession fixture; each test rolls
back so they don't pollute each other. Also includes a sync Session
fixture (db_sync) for the Importer tests in Task 5.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>