Commit Graph

2 Commits

Author SHA1 Message Date
b221acee40 Implement automatic Garmin token refresh and fix expiry tracking
- Add OAuth1 to OAuth2 token exchange using Garmin's exchange endpoint
- Track refresh token expiry (~30 days) instead of access token expiry (~21 hours)
- Auto-refresh access tokens in cron sync before they expire
- Update Python script to output refresh_token_expires_at
- Add garminRefreshTokenExpiresAt field to User type and database schema
- Fix token input UX: show when warning active, not just when disconnected
- Add Cache-Control headers to /api/user and /api/garmin/status to prevent stale data
- Add oauth-1.0a package for OAuth1 signature generation

The system now automatically refreshes OAuth2 tokens using the stored OAuth1 token,
so users only need to re-run the Python auth script every ~30 days (when refresh
token expires) instead of every ~21 hours (when access token expires).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-14 20:33:10 +00:00
901543cb4d Implement notifications cron endpoint (P2.5)
Add daily email notification system that sends training decisions
at each user's preferred time in their timezone.

Features:
- Timezone-aware notification matching using Intl.DateTimeFormat
- DailyLog-based notifications with duplicate prevention
- Nutrition guidance integration via getNutritionGuidance
- Graceful error handling (continues processing on per-user failures)
- Summary response with detailed stats

Includes 20 tests covering:
- CRON_SECRET authentication
- Timezone matching (UTC and America/New_York)
- DailyLog existence and already-sent checks
- Email content assembly
- Error handling and response format

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 19:56:16 +00:00