mirror of
https://github.com/maziggy/bambuddy.git
synced 2026-09-30 03:01:21 +02:00
feat(sponsor-prompt): lower print/archive/cost thresholds to fire for typical new installs
The toast was calibrated for power users — lowest bars were 100 prints,
50 archives, 100 cost. Most installs never crossed any of them, especially
with the install base ~doubling since March. Matomo confirms: only 4
prints-100 and 3 archives-50 deeplink visits to /sponsors.html in a 7-day
window despite tens of thousands of weekly pulls.
Adds lower thresholds without changing priority order or cooldown:
PRINT_MILESTONES = (10, 25, ...)
ARCHIVE_MILESTONES = (5, 10, ...)
COST_MILESTONES = (25, 50, ...)
Existing toast copy uses {count}/{total} interpolation in all 11 locales,
so no i18n changes. Tests rebalanced so "below the floor" still tests
with the new floor; new test_fires_at_lowest_threshold pins prints-10.
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -32,9 +32,9 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
COOLDOWN_DAYS = 14
|
||||
|
||||
PRINT_MILESTONES = (100, 500, 1000, 2500, 5000)
|
||||
COST_MILESTONES = (100, 500, 1000)
|
||||
ARCHIVE_MILESTONES = (50, 250, 1000)
|
||||
PRINT_MILESTONES = (10, 25, 100, 500, 1000, 2500, 5000)
|
||||
COST_MILESTONES = (25, 50, 100, 500, 1000)
|
||||
ARCHIVE_MILESTONES = (5, 10, 50, 250, 1000)
|
||||
ANNIVERSARY_YEARS = 1
|
||||
|
||||
|
||||
|
||||
@@ -155,15 +155,24 @@ class TestPrintMilestones:
|
||||
assert trigger is not None
|
||||
assert trigger.milestone == "prints-100"
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_fires_at_lowest_threshold(self, db_session: AsyncSession):
|
||||
user = await _make_user(db_session)
|
||||
await _add_completed_prints(db_session, user_id=user.id, count=10)
|
||||
trigger = await service.evaluate(db_session, user.id)
|
||||
assert trigger is not None
|
||||
assert trigger.milestone == "prints-10"
|
||||
assert trigger.threshold == 10
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_failed_prints_dont_count(self, db_session: AsyncSession):
|
||||
user = await _make_user(db_session)
|
||||
await _add_completed_prints(db_session, user_id=user.id, count=50)
|
||||
await _add_completed_prints(db_session, user_id=user.id, count=5)
|
||||
for _ in range(60):
|
||||
db_session.add(PrintLogEntry(status="failed", created_by_id=user.id))
|
||||
await db_session.flush()
|
||||
trigger = await service.evaluate(db_session, user.id)
|
||||
# Only 50 completed → below 100 threshold → no print trigger.
|
||||
# Only 5 completed → below 10 threshold → no print trigger.
|
||||
# Anniversary not reached either; no other counter populated.
|
||||
assert trigger is None
|
||||
|
||||
@@ -181,10 +190,10 @@ class TestArchiveMilestones:
|
||||
class TestCostMilestones:
|
||||
@pytest.mark.asyncio
|
||||
async def test_fires_when_cost_sum_crosses_100(self, db_session: AsyncSession):
|
||||
# Prints with cost = ~3.5 each, 30 prints → 105.
|
||||
# 5 prints, cost ~21 each → 105 total. Below the 10-print threshold so
|
||||
# the prints family stays silent and cost gets a chance.
|
||||
user = await _make_user(db_session)
|
||||
await _add_completed_prints(db_session, user_id=user.id, count=30, cost_each=3.5)
|
||||
# 30 < 100 prints, so prints-100 not eligible. cost = 105 ≥ 100 → fires.
|
||||
await _add_completed_prints(db_session, user_id=user.id, count=5, cost_each=21.0)
|
||||
trigger = await service.evaluate(db_session, user.id)
|
||||
assert trigger is not None
|
||||
assert trigger.family == "cost"
|
||||
|
||||
Reference in New Issue
Block a user