feat: revamp points/reward system for inclusive engagement

- /city /deb now free, capped at 10/day each (was 2 pts cost)
- Welcome bonus +20 pts on first-ever valid message
- First-message-of-day bonus +2 pts
- Weekly winner point bonuses reduced (500→200, 300→100, 150→50)
- Weekly participation rewards for all active users (+5 base, +15 for ≥20 pts)
- Pro-day rewards for top 3 unchanged

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
AmandaloveYang
2026-05-11 13:35:52 +08:00
co-authored by Claude Opus 4.7
parent 81e9aeb98f
commit 787d04619b
8 changed files with 215 additions and 27 deletions
+4 -1
View File
@@ -10,7 +10,7 @@ from src.bot.command_guard import CommandGuard
from src.bot.io_layer import BotIOLayer
from src.bot.observability import CommandTrace
from src.bot.services.city_command_service import CityCommandService
from src.bot.settings import CITY_QUERY_COST
from src.bot.settings import CITY_DAILY_FREE_LIMIT, CITY_QUERY_COST
def _is_city_command(message: Any) -> bool:
command = extract_command_name(
@@ -77,6 +77,9 @@ class CityCommandHandler:
return
city_name = str(resolved.city_name)
if not self.guard.check_daily_query_limit(message, "city", CITY_DAILY_FREE_LIMIT):
trace.set_status("blocked", "daily_query_limit")
return
if not self.guard.ensure_access_and_points(message, CITY_QUERY_COST, "/city"):
trace.set_status("blocked", "guard_rejected")
return
+4 -1
View File
@@ -10,7 +10,7 @@ from src.bot.command_guard import CommandGuard
from src.bot.io_layer import BotIOLayer
from src.bot.observability import CommandTrace
from src.bot.services.deb_command_service import DebCommandService
from src.bot.settings import DEB_QUERY_COST
from src.bot.settings import DEB_DAILY_FREE_LIMIT, DEB_QUERY_COST
def _is_deb_command(message: Any) -> bool:
command = extract_command_name(
@@ -75,6 +75,9 @@ class DebCommandHandler:
)
return
if not self.guard.check_daily_query_limit(message, "deb", DEB_DAILY_FREE_LIMIT):
trace.set_status("blocked", "daily_query_limit")
return
if not self.guard.ensure_access_and_points(message, DEB_QUERY_COST, "/deb"):
trace.set_status("blocked", "guard_rejected")
return