From 7d2507a9277642e8c3a0efc95c3906be2bf7a0a2 Mon Sep 17 00:00:00 2001 From: Inferencebot Date: Sat, 31 Oct 2026 16:49:22 +0000 Subject: [PATCH] portal: 90% threshold for budget notices; sweep 3x a day Trigger becomes proportional (90% of the balance used) instead of a $2 floor, so a member on $15 and one on $35 are treated the same. The once-per-crossing latch keys on the same fraction. membership_sweep moves from '0 3 * * *' to '0 3,11,19 * * *' so the notice arrives within hours of crossing rather than up to a day later. BUDGET_NOTICES remains off. --- CloudronManifest.json | 2 +- app/main.py | 15 ++++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/CloudronManifest.json b/CloudronManifest.json index e7afc87..ec5990e 100644 --- a/CloudronManifest.json +++ b/CloudronManifest.json @@ -15,7 +15,7 @@ "sendmail": {}, "scheduler": { "membership_sweep": { - "schedule": "0 3 * * *", + "schedule": "0 3,11,19 * * *", "command": "/app/code/sweep.sh" }, "rag_refresh": { diff --git a/app/main.py b/app/main.py index 4b2aa8c..29b7e16 100644 --- a/app/main.py +++ b/app/main.py @@ -3973,9 +3973,10 @@ async def index(): # Generic on purpose: the balance can be short because the monthly allowance is spent, # because purchased credit is spent, or a mix — the letter says "balance" so it is true -# either way. The trigger is an absolute floor, not a percentage, so it means the same -# thing to a member on a $15 allowance and a member on $35. -BUDGET_LOW_WATER = float(os.environ.get("BUDGET_LOW_WATER", "2.00")) +# either way. The trigger is proportional — 90% of the balance used — so it means the same +# thing to a member on $15 and one on $35: the letter arrives when roughly a tenth is left, +# on whichever sweep follows, rather than at an arbitrary absolute amount. +BUDGET_NOTICE_AT = float(os.environ.get("BUDGET_NOTICE_AT", "0.90")) PINE_LOGO_SVG = """