2.7 KiB
2.7 KiB
Notifications Specification
Job to Be Done
When I wake up each morning, I want to receive an email with my training decision, so that I don't need to open the app to know if I should train.
Email Notifications
Daily Training Email
Sent at user's preferred notificationTime (default: 07:00).
Subject:
PhaseFlow: [STATUS] - Day [cycleDay] ([phase])
Example: PhaseFlow: ✅ TRAIN - Day 12 (FOLLICULAR)
Body:
Good morning!
Today's Decision: [STATUS]
Reason: [reason]
Current Metrics:
- Cycle Day: [cycleDay] ([phase])
- Body Battery: [bbCurrent]
- HRV: [hrvStatus]
- Week Intensity: [weekIntensity]/[phaseLimit] min
Nutrition Today:
- Seeds: [seeds]
- Carbs: [carbRange]
- Keto: [ketoGuidance]
[Optional: Seed switch alert if day 15]
[Optional: Token expiration warning]
---
PhaseFlow - Training with your cycle, not against it
Token Expiration Warnings
14 Days Before:
Subject: ⚠️ PhaseFlow: Garmin tokens expire in 14 days
7 Days Before:
Subject: 🚨 PhaseFlow: Garmin tokens expire in 7 days - action required
Email Provider
Using Resend via resend npm package.
Configuration:
RESEND_API_KEY- API key for ResendEMAIL_FROM- Sender address (e.g.,PhaseFlow <noreply@phaseflow.app>)
Email Utilities (src/lib/email.ts)
Functions:
sendDailyNotification(user, decision, dailyData)- Send morning emailsendTokenExpirationWarning(user, daysUntilExpiry)- Send warning email
Cron Jobs
/api/cron/notifications
Protected by CRON_SECRET header.
Trigger: Daily at notification times
Process:
- Find all users with
notificationTimematching current hour - For each user:
- Fetch current decision from decision engine
- Send email via Resend
- Update
DailyLog.notificationSentAt
Timezone Handling
Users store preferred timezone (e.g., America/New_York).
Cron runs every hour. Check if current hour in user's timezone matches their notificationTime.
Rate Limiting
- Max 1 notification per user per day
- Check
DailyLog.notificationSentAtbefore sending - Only send if null or different date
Success Criteria
- Email arrives within 5 minutes of scheduled time
- Email contains all relevant metrics and guidance
- Token warnings sent at 14 and 7 day thresholds
- No duplicate notifications on same day
Acceptance Tests
- Daily email contains decision status and reason
- Daily email includes nutrition guidance
- Seed switch alert included on day 15
- Token warning email sent at 14-day threshold
- Token warning email sent at 7-day threshold
- Duplicate notifications prevented
- Timezone conversion correct for notification time
- CRON_SECRET required for endpoint access