Skip to content

feat(subscription_manager): per-user trial daily caps and no-expiry mode - #116

Merged
calmmage merged 3 commits into
mainfrom
feat/trial-daily-cap
Sep 29, 2026
Merged

calmmage merged 3 commits into
mainfrom
feat/trial-daily-cap

Conversation

@calmmage

Copy link
Copy Markdown
Owner

Public free 20 min/day needs code (not the default). This adds optional per-user UTC daily trial caps and a no-expiry trial mode.

What

  • New settings (env prefix BOTSPOT_SUBSCRIPTION_MANAGER_, 0 = off):
    • TRIAL_USER_AUDIO_MINUTES_PER_DAY
    • TRIAL_USER_AUDIO_REQUESTS_PER_DAY
    • TRIAL_USER_CHAT_REQUESTS_PER_DAY
  • Caps sit in addition to existing lifetime totals and global daily caps. Usage is one trial_daily_usage doc per user per UTC day (_id = {user_id}:{YYYY-MM-DD}), incremented with atomic $inc.
  • TRIAL_DURATION_DAYS=0 means no expiry (public free tier). Default remains 7.
  • Hitting a per-user daily cap: Decision.reason = trial_daily_cap. The i18n string includes minutes left today and the UTC reset time. Existing subscribe upsell keyboard is unchanged.
  • Entitlement order unchanged: admin → friend → subscription/manual → credits → trial. Friends never hit the cap.

Tests

uv run pytest tests/components/test_subscription_manager.py — all existing tests plus:

  • test_per_user_daily_cap_across_day_boundary
  • test_per_user_daily_request_caps
  • test_trial_duration_zero_means_no_expiry

ruff clean. pyright clean on botspot/components/new/subscription_manager. Full suite 262 passed, coverage 70%.

Whisper env names (not the default)

For public free 20 min/day:

BOTSPOT_SUBSCRIPTION_MANAGER_TRIAL_DURATION_DAYS=0
BOTSPOT_SUBSCRIPTION_MANAGER_TRIAL_USER_AUDIO_MINUTES_PER_DAY=20

Lifetime totals still apply unless also set to 0 (off).

Do not merge.

🤖 Generated with Claude Code

calmmage and others added 3 commits September 19, 2026 09:12
Public free tier: trial_duration_days=0 means no expiry. Optional per-user
UTC daily caps (0 = off) for audio minutes/requests and chat requests.
Hitting a daily cap sets Decision.reason=trial_daily_cap and an i18n
string with minutes left today and the UTC reset time.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Extract lifetime/global/per-user daily cap helpers so reserve and
authorize stay under the advisory lizard limit.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
# Conflicts:
#	botspot/components/new/subscription_manager/__init__.py
#	examples/components_examples/subscription_manager_demo/README.md
#	tests/components/test_subscription_manager.py
@calmmage
calmmage merged commit 53db366 into main Sep 29, 2026
11 checks passed
@calmmage
calmmage deleted the feat/trial-daily-cap branch September 29, 2026 10:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant