mirror of
https://github.com/escalante29/healthy-fit.git
synced 2026-03-21 12:48:47 +01:00
- Supplement tracking: CRUD endpoints, /today, /logs, Supplements page - Kettlebell workouts: session tracking, analytics endpoint, ActiveSession page - Calendar module: events CRUD, calendar components - Push notifications: VAPID keys, PushSubscription model, APScheduler reminders, service worker with push/notificationclick handlers, Profile notifications UI - PWA: vite-plugin-pwa, manifest, icons, service worker generation - Frontend: TypeScript types, API modules, ConfirmModal, toast notifications - Auth fixes: password hashing, nutrition endpoint auth - CLAUDE.md: project documentation and development guide Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
48 lines
1.4 KiB
Python
48 lines
1.4 KiB
Python
from datetime import datetime, timezone
|
|
|
|
import pytz
|
|
from apscheduler.schedulers.background import BackgroundScheduler
|
|
from apscheduler.triggers.cron import CronTrigger
|
|
from sqlmodel import Session, select
|
|
|
|
from app.db import engine
|
|
from app.models.push_subscription import PushSubscription
|
|
|
|
scheduler = BackgroundScheduler(timezone="UTC")
|
|
|
|
|
|
def send_supplement_reminders() -> None:
|
|
from app.api.v1.endpoints.push import send_push
|
|
|
|
now_utc = datetime.now(timezone.utc)
|
|
with Session(engine) as session:
|
|
subs = session.exec(
|
|
select(PushSubscription).where(PushSubscription.is_active == True) # noqa: E712
|
|
).all()
|
|
due = []
|
|
for sub in subs:
|
|
try:
|
|
tz = pytz.timezone(sub.timezone)
|
|
local_now = now_utc.astimezone(tz)
|
|
if local_now.hour == sub.reminder_hour and local_now.minute == sub.reminder_minute:
|
|
due.append(sub)
|
|
except Exception:
|
|
pass
|
|
if due:
|
|
send_push(due, title="Supplement Reminder", body="Time to log your supplements for today!", session=session)
|
|
session.commit()
|
|
|
|
|
|
def start_scheduler() -> None:
|
|
scheduler.add_job(
|
|
send_supplement_reminders,
|
|
CronTrigger(minute="*"),
|
|
id="supplement_reminders",
|
|
replace_existing=True,
|
|
)
|
|
scheduler.start()
|
|
|
|
|
|
def stop_scheduler() -> None:
|
|
scheduler.shutdown(wait=False)
|