32bdde049f
_find_or_create_source, _source_for_sidecar, and _find_or_create_post each repeated the SELECT → savepoint-INSERT → on-IntegrityError rollback+re-SELECT pattern. Extracted _get_or_create(stmt, factory): the statement is reused for the scalar_one_or_none lookup and the scalar_one post-conflict re-fetch, so all three are reproduced exactly. Centralizing the race-safe pattern in one place also reduces the risk of the copies drifting (the bug class banked 2026-05-26). Left _upsert_artist (no savepoint by design) and the ImageProvenance void ensure-exists block (no return / no re-select) alone — they don't fit. The rest of the ingest pipeline was already DRY: sidecar parsing lives in utils/sidecar.py, per-platform quirks in the platforms package, and _safe_ext/_categorize_error/_build_config are each single-instance. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>