Polish video import: thumbnails, quota refunds, SSRF-hardened download#91
Merged
Conversation
Production hardening for the two live platforms (TikTok, Instagram): - Thumbnail: a representative sampled frame (the middle one) is uploaded to S3 and set as the recipe's hero image (imageUrl was empty before). The URL is stored on the VideoExtractionCache (additive column) so cache hits reuse the same image at no extra cost. Best-effort — an upload failure never fails the import. - Quota refund: video quota is consumed on acceptance to bound concurrency, but is now refunded (DecrementUsage, floored at zero) when the job later fails on our side, so a user never loses an import to an infra error. - SSRF: the frame sampler's HTTP client now blocks connections to private/internal IPs at dial time via net.Dialer.Control, covering the initial host, every redirect hop, and DNS rebinding — the scraper-supplied media URL is untrusted. Tests (offline, race-clean): safeDialControl block/allow table; thumbnail set on fresh import + reused on cache hit; quota refunded on failure (via a lock-synchronized mock getter). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BU4UWZutHd1AnK3XAf7H19
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Production hardening for the two live video-import platforms (TikTok #89, Instagram #90), per the "polish what's live" direction. Three independent improvements, all backend-only:
1. Recipe thumbnails
Video imports had an empty
imageUrl. Now a representative sampled frame (the middle one — past any intro, before any outro) is uploaded to S3 and set as the recipe's hero image. The URL is stored onVideoExtractionCache(additive column, dashboard-safe) so cache hits reuse the same image at no extra cost. Best-effort: an upload failure never fails the import.2. Quota refunds on our-side failures
Video quota is consumed on acceptance (bounds concurrent-spam), but a job that later fails on our side (fetch error, frame sampling, extraction, at-capacity) now refunds the quota unit (
DecrementUsage, floored at zero). A user never loses one of their monthly imports to an infra error — which the earlier Anthropic-credits outage showed is a real scenario.3. SSRF-hardened media download
The frame sampler downloads a scraper-supplied (untrusted) media URL. Its HTTP client now blocks connections to private/internal IPs at dial time via
net.Dialer.Control, which runs post-DNS-resolution — so it covers the initial host, every redirect hop, and DNS rebinding alike (the prior upfrontValidateExternalURLcheck was TOCTOU/redirect-blind).Tests (offline, race-clean)
TestSafeDialControl— loopback/private/link-local/unspecified blocked; public allowed.TestVideoImport_SetsThumbnail— middle frame uploaded, set on recipe + cached.TestVideoImport_CacheHitReusesThumbnail— cache hit reuses the stored thumbnail.TestVideoImport_RefundsQuotaOnFailure— failed import refunds quota (asserted via a lock-synchronized mock getter to avoid racing the async refund).Schema
Adds
thumbnail_urltovideo_extraction_caches(additive; AutoMigrate handles it). No changes to existing columns.🤖 Generated with Claude Code
https://claude.ai/code/session_01BU4UWZutHd1AnK3XAf7H19