feat: what you pay for, against what FC actually follows (387 C4)
CI / lint (push) Successful in 2s
Build images / sign-extension (push) Successful in 3s
CI / extension-version (push) Successful in 2s
Build images / build-agent (push) Successful in 5s
CI / frontend-build (push) Successful in 21s
CI / backend-lint-and-test (push) Successful in 32s
Build images / build-web (push) Successful in 1m18s
Build images / smoke-web (push) Skipped
Build images / build-ml (push) Successful in 2m11s
Build images / promote (push) Skipped
CI / integration (push) Successful in 3m4s
CI / lint (push) Successful in 2s
Build images / sign-extension (push) Successful in 3s
CI / extension-version (push) Successful in 2s
Build images / build-agent (push) Successful in 5s
CI / frontend-build (push) Successful in 21s
CI / backend-lint-and-test (push) Successful in 32s
Build images / build-web (push) Successful in 1m18s
Build images / smoke-web (push) Skipped
Build images / build-ml (push) Successful in 2m11s
Build images / promote (push) Skipped
CI / integration (push) Successful in 3m4s
Reconciliation in Subscriptions, asymmetric on purpose. Subscriptions FC does not follow get a per-row add; sources the roster cannot account for are REPORT ONLY (operator decision) and link to the list on the same page. No one-click disable, so no disabled-reason column and no migration. The membership<->source join lands as a SHARED resolver in membership_roster, not inline here: E4 now uses it as its negative check, so the two features cannot give different answers to 'is this membership already tracked?'. Keys on the exact cached campaign id FIRST and the URL handle only as fallback, because the id is written only after a source has been walked once. Read via any <platform>_campaign_id override rather than naming Patreon's, per rule 169. The report-only bucket is gated on roster freshness and carries a per-row basis, so 'your membership says former patron', 'we know this id and it is absent', and 'we only have a handle' stay three different sentences. has_paid_access None never reads as lapsed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LNXXULQDjVZmbuNa2G9mD9
This commit is contained in:
@@ -75,6 +75,7 @@ from ..models import (
|
||||
)
|
||||
from ..utils.slug import slugify
|
||||
from ..utils.text import html_to_plain
|
||||
from .membership_roster import source_for_membership
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@@ -204,6 +205,14 @@ class ArtistMembershipService:
|
||||
membership = await self.session.get(PlatformMembership, membership_id)
|
||||
if membership is None:
|
||||
return 0
|
||||
# The shared identity join (C4), used here as the NEGATIVE check. A
|
||||
# membership FC already has a source for is tracked — whoever it happens
|
||||
# to be filed under — and proposing it to some OTHER artist would be
|
||||
# exactly the wrong link this service exists to avoid making.
|
||||
# `_candidate_artists` only knows whether a GIVEN artist has a source on
|
||||
# the platform, which cannot see a source sitting under someone else.
|
||||
if await source_for_membership(self.session, membership) is not None:
|
||||
return 0
|
||||
already = await self._decided(membership_id)
|
||||
|
||||
made = 0
|
||||
|
||||
Reference in New Issue
Block a user