Merges two CI-green dev commits to main so they reach `:latest`:
- **#859** — external-download attach orphan fix: per-link staging dir, path-safe unlink (never delete a file an ImageRecord points to), and an operator-triggered orphan-repair maintenance task with an NFS-stall abort guard. Fixes the 404-on-playback bug (TentaTime_Act3, StickySpoodge "Industrial Lust"). + regression tests.
- **f897e25** — full-width body for image-less posts (drops the dead "no images" box).
No new migrations. No new runtime deps (the megatools/gdown image is unchanged) — but `:latest` still needs a forced re-pull after merge.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Text-only Patreon posts (WIP/announcement/poll — the bulk of a creator's feed)
rendered a big empty 'No images attached to this post' placeholder taking half
the card. Render the media column only when the post HAS images; image-less posts
let the title + body span the full width. Removes the now-dead PostEmptyThumbs.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
External downloads import IN PLACE, so the post-attach dedup-skip unlink could
delete a file that IS an ImageRecord's backing file — orphaning the record and
404-ing on playback. Two sources of that:
- Two links on the same post (same film from mega + gdrive) emitted the same
filename into one external/<post_id>/ dir; the second overwrote the first.
Stage per-LINK now (external/<post_id>/<link_id>/) so each file keeps its path.
- The duplicate_hash/duplicate_phash branch unlinked `f` unconditionally. Make it
path-safe: only unlink when `f` is NOT the existing record's canonical file.
Plus an operator-triggered orphan-repair maintenance task
(prune_missing_file_records_task) to clean up records already orphaned by the
bug: scans ImageRecords, deletes those whose file is gone (cascade), with an
NFS-stall guard that aborts without deleting if a large sample is mostly missing.
Wired through POST /api/admin/maintenance/prune-missing-files and a
MissingFileRepairCard in the Maintenance panel.
Tests: refetch-same-link keeps the canonical file; orphan repair deletes only
real orphans and aborts on the mostly-missing guard.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Merges two CI-green dev commits to main so they reach
:latest:f897e25— full-width body for image-less posts (drops the dead "no images" box).No new migrations. No new runtime deps (the megatools/gdown image is unchanged) — but
:lateststill needs a forced re-pull after merge.🤖 Generated with Claude Code