# 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 Resend - `EMAIL_FROM` - Sender address (e.g., `PhaseFlow `) ## Email Utilities (`src/lib/email.ts`) **Functions:** - `sendDailyNotification(user, decision, dailyData)` - Send morning email - `sendTokenExpirationWarning(user, daysUntilExpiry)` - Send warning email ## Cron Jobs ### `/api/cron/notifications` Protected by `CRON_SECRET` header. **Trigger:** Daily at notification times **Process:** 1. Find all users with `notificationTime` matching current hour 2. 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.notificationSentAt` before sending - Only send if null or different date ## Success Criteria 1. Email arrives within 5 minutes of scheduled time 2. Email contains all relevant metrics and guidance 3. Token warnings sent at 14 and 7 day thresholds 4. 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