Briefing slots (4am/8am/12pm/4pm) now fire in each user's local timezone
rather than UTC, so the schedule matches the user's actual day.
Backend:
- briefing_scheduler: replaced 4 global UTC cron jobs with per-user
CronTrigger jobs keyed to the user's IANA timezone; update_user_schedule()
live-patches the scheduler when config is saved (no restart needed)
- Catchup logic evaluates missed slots in the user's local timezone
- put_config route calls update_user_schedule() after saving
Frontend:
- New Timezone section in Briefing settings: text input pre-filled from
browser (Intl.DateTimeFormat) with a Detect button for re-detection
- Slot times shown as fixed local times (4:00 am etc.) with the configured
timezone displayed beneath, replacing the old UTC-conversion display
- timezone field added to BriefingConfig type and default
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>