fix(ingest): skip tier-gated Patreon posts entirely (#874)
CI / lint (push) Failing after 3s
CI / frontend-build (push) Successful in 19s
CI / backend-lint-and-test (push) Successful in 33s
CI / integration (push) Failing after 3m20s

Patreon serves only blurred locked-preview thumbnails for posts the
authenticated account can't fully view; the native ingester was
downloading those as real media. current_user_can_view was already in
_FIELDS_POST but never read.

Add PatreonClient.post_is_gated (gate ONLY on explicit
current_user_can_view=False; missing/None → viewable, never over-filter)
and skip gated posts at the top of the ingest_core run() and preview()
loops — no media download AND no post-record stub (operator: 'no stub
for gated content'). Skipped before the post-record block so gated posts
never inflate the #862 body canary; surfaced as 'N gated-skipped' in the
run summary. Same gate in preview() for preview/apply parity (rule 93).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-16 14:43:00 -04:00
parent 60a9c9e6ef
commit b3afc2437e
4 changed files with 125 additions and 1 deletions
+24
View File
@@ -435,3 +435,27 @@ def test_post_record_key_returns_synthetic_key_and_id():
def test_post_record_key_none_without_id():
assert PatreonClient.post_record_key({}) is None
assert PatreonClient.post_record_key({"id": None}) is None
# -- post_is_gated (#874 tier-gated access filter) --------------------------
def test_post_is_gated_only_on_explicit_false():
# The blurred-preview case: account can't view the post → gate it.
assert PatreonClient.post_is_gated(
{"attributes": {"current_user_can_view": False}}
) is True
def test_post_is_gated_viewable_and_missing_are_not_gated():
# Explicit True, a missing flag, an explicit None, and a missing attributes
# block ALL count as viewable — gate only on an explicit False so an absent
# field never over-filters accessible posts.
assert PatreonClient.post_is_gated(
{"attributes": {"current_user_can_view": True}}
) is False
assert PatreonClient.post_is_gated({"attributes": {}}) is False
assert PatreonClient.post_is_gated(
{"attributes": {"current_user_can_view": None}}
) is False
assert PatreonClient.post_is_gated({}) is False