beta-launch: respect returning-user opt-out + show digest job in ops LEDs

- verify_submit now applies the subscribe checkbox only at first sign-up.
  Returning users keep whatever they set via Settings or the one-click
  unsubscribe link — previously, every login silently re-enrolled them.
- JOB_NAMES gains email_digest_job so the ops footer reflects its health.

Adds tests/test_verify_subscribe.py::test_returning_user_login_preserves_unsubscribe.
This commit is contained in:
Giorgio Gilestro 2026-05-25 23:33:53 +02:00
parent 5046be915b
commit e338650dfa
3 changed files with 54 additions and 3 deletions

View file

@ -50,7 +50,8 @@ from app.schemas import (
router = APIRouter(dependencies=[Depends(require_token)])
JOB_NAMES = ("market_job", "news_job", "ai_log_job", "rollup_job",
"indicator_summary_job", "universe_flush_job")
"indicator_summary_job", "universe_flush_job",
"email_digest_job")
JOB_STALE_HOURS = 2.0 # job is "warn" if its last success was >2h ago
# Per-group expected freshness — bonds and intraday tape want daily data,

View file

@ -240,9 +240,14 @@ async def verify_submit(
if user is None:
# User row vanished between cookie issue and verify. Restart flow.
return RedirectResponse(url="/login", status_code=303)
is_first_login = user.last_login_at is None
user.last_login_at = utcnow()
# An unchecked HTML checkbox sends NO field; that means "opt out".
user.email_digest_opt_in = subscribe_to_digests is not None
# Apply the verify-page subscribe checkbox ONLY at first sign-up. After
# that, Settings (and the one-click unsubscribe link) own the preference
# — re-applying on every login would silently re-subscribe users who
# explicitly opted out.
if is_first_login:
user.email_digest_opt_in = subscribe_to_digests is not None
await session.commit()
log.info("user.login", user_id=user.id, email=email)