Add activity push notifications and registration patches

This commit is contained in:
2026-09-15 08:31:45 +02:00
parent 7c801dfddd
commit 55174684af
38 changed files with 1096 additions and 42 deletions
+43
View File
@@ -0,0 +1,43 @@
"""Exclusive cohorts; convert legacy DB-local registration timestamps to Europe/Berlin."""
from datetime import date, datetime, time, timedelta
import os
from zoneinfo import ZoneInfo
COHORTS = ('alpha_tester', 'beta_tester', 'early_bird')
def boundaries():
alpha = date.fromisoformat(os.environ.get('ALPHA_TESTER_UNTIL', '2026-10-31'))
beta = date.fromisoformat(os.environ.get('BETA_TESTER_UNTIL', '2026-12-31'))
if beta <= alpha:
raise ValueError('BETA_TESTER_UNTIL must be after ALPHA_TESTER_UNTIL')
return (datetime.combine(alpha + timedelta(days=1), time()),
datetime.combine(beta + timedelta(days=1), time()))
def cohort(registered_at):
if registered_at.tzinfo:
registered_at = registered_at.astimezone(ZoneInfo('Europe/Berlin')).replace(tzinfo=None)
alpha_end, beta_end = boundaries()
return 'alpha_tester' if registered_at < alpha_end else 'beta_tester' if registered_at < beta_end else 'early_bird'
def reconcile(cursor, user_id=None):
"""Also upgrades existing beta members and reclassifies when configured dates change."""
alpha_end, beta_end = boundaries()
cursor.execute('''
DELETE FROM user_badges b USING users u WHERE b.user_id=u.id
AND (%s::integer IS NULL OR u.id=%s)
AND b.badge_code=ANY(%s) AND b.badge_code <> CASE
WHEN u.created_at AT TIME ZONE current_setting('TimeZone') AT TIME ZONE 'Europe/Berlin' < %s THEN 'alpha_tester'
WHEN u.created_at AT TIME ZONE current_setting('TimeZone') AT TIME ZONE 'Europe/Berlin' < %s THEN 'beta_tester' ELSE 'early_bird' END
''', (user_id, user_id, list(COHORTS), alpha_end, beta_end))
cursor.execute('''
INSERT INTO user_badges(user_id,badge_code,awarded_at)
SELECT id, CASE
WHEN created_at AT TIME ZONE current_setting('TimeZone') AT TIME ZONE 'Europe/Berlin' < %s THEN 'alpha_tester'
WHEN created_at AT TIME ZONE current_setting('TimeZone') AT TIME ZONE 'Europe/Berlin' < %s THEN 'beta_tester'
ELSE 'early_bird' END, created_at
FROM users WHERE (%s::integer IS NULL OR id=%s)
ON CONFLICT(user_id,badge_code) DO NOTHING
''', (alpha_end, beta_end, user_id, user_id))