fix(hc warmup): only mail slightly-overdue providers (deliverability)
Mailing heavily-overdue NPIs (months/years past due) risks hitting practices that have closed, merged, or abandoned the inbox -> hard bounces, which are the fastest way to wreck a warming IP's reputation. The warmup now restricts the reval_overdue selector to an inclusive [HC_OVERDUE_MIN, HC_OVERDUE_MAX] window (default 1-90 days) and the OIG 'any' selector likewise excludes heavily-overdue and dropped-off-list rows. On the current cohort this trims the overdue audience 178->96 and the OIG audience 399->317, holding out the stale long tail (181-365d + 366d+). upcoming/active providers are unaffected.
This commit is contained in:
parent
c79a7715e1
commit
feb677f6ce
2 changed files with 37 additions and 2 deletions
|
|
@ -4,4 +4,7 @@
|
|||
# America/Chicago). Delivery is throttled by pw-hc-rampcap's sliding-window
|
||||
# cap, sent ONLY via the hc HOT stream (.107-.109). Segment audiences are
|
||||
# source-grounded: a segment with no matching providers simply imports nobody.
|
||||
# Deliverability guard: warmup only mails SLIGHTLY-overdue providers (1-90 days
|
||||
# by default, HC_OVERDUE_MIN/MAX) -- recently-lapsed practices still have live
|
||||
# inboxes; heavily-overdue ones likely bounce and burn the warming IPs.
|
||||
0 7 * * 1-5 deploy cd /opt/performancewest && HC_VERIFIED_CSV=/opt/performancewest/data/hc_warmup_nongoogle.csv python3 scripts/build_healthcare_campaigns_cron.py --start-campaign >> /var/log/pw-hc-campaign.log 2>&1
|
||||
|
|
|
|||
|
|
@ -67,6 +67,22 @@ ACTIVE_SEGMENTS = os.getenv(
|
|||
"revalidation_overdue,oig_screening,nppes_outdated,npi_reactivation,compliance_bundle",
|
||||
).split(",")
|
||||
|
||||
# Warmup deliverability guard: only mail SLIGHTLY-overdue providers. A practice
|
||||
# that lapsed recently is almost certainly still operating with a live inbox; one
|
||||
# that is many months/years overdue has likely closed, merged, or abandoned the
|
||||
# address, so its mail bounces -- and bounces are the fastest way to wreck a
|
||||
# warming IP's reputation. Window is inclusive [MIN, MAX] days overdue.
|
||||
WARMUP_OVERDUE_MIN = int(os.getenv("HC_OVERDUE_MIN", "1"))
|
||||
WARMUP_OVERDUE_MAX = int(os.getenv("HC_OVERDUE_MAX", "90"))
|
||||
|
||||
|
||||
def _overdue_days(r: dict):
|
||||
v = (r.get("days_overdue") or "").strip()
|
||||
try:
|
||||
return int(v)
|
||||
except ValueError:
|
||||
return None
|
||||
|
||||
|
||||
def warmup_day() -> int:
|
||||
try:
|
||||
|
|
@ -197,14 +213,30 @@ def row_matches(seg_key: str, r: dict) -> bool:
|
|||
status = (r.get("reval_status") or "").strip().lower()
|
||||
excluded = (r.get("leie_excluded") or "").strip() not in ("", "0", "false")
|
||||
optout = (r.get("optout_ending") or "").strip() != ""
|
||||
if sel == "reval_overdue": return status == "overdue"
|
||||
if sel == "reval_overdue":
|
||||
# Only SLIGHTLY-overdue: recently-lapsed practices are still active with
|
||||
# deliverable inboxes. Heavily-overdue ones likely bounce and burn the
|
||||
# warming IP's reputation, so we hold them out of the warmup window.
|
||||
if status != "overdue":
|
||||
return False
|
||||
od = _overdue_days(r)
|
||||
return od is not None and WARMUP_OVERDUE_MIN <= od <= WARMUP_OVERDUE_MAX
|
||||
if sel == "reval_upcoming": return status == "upcoming"
|
||||
if sel == "leie_or_deactivated":
|
||||
# Reactivation targets: flagged excluded, OR no longer on the reval list
|
||||
# (a strong deactivation proxy once revalidation lapses).
|
||||
return excluded or status in ("not_on_list", "no_reval_flag")
|
||||
if sel == "optout_ending": return optout
|
||||
if sel == "any": return True
|
||||
if sel == "any":
|
||||
# OIG screening applies to any billing practice, but for warmup we still
|
||||
# exclude the likely-undeliverable: providers heavily overdue (stale) or
|
||||
# already dropped off the reval list. Recently-lapsed and upcoming stay.
|
||||
if status in ("not_on_list", "no_reval_flag"):
|
||||
return False
|
||||
od = _overdue_days(r)
|
||||
if status == "overdue" and (od is None or od > WARMUP_OVERDUE_MAX):
|
||||
return False
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue