44 lines
2.2 KiB
Python
44 lines
2.2 KiB
Python
"""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))
|